diff --git a/v2/pkg/variablesvalidation/variablesvalidation.go b/v2/pkg/variablesvalidation/variablesvalidation.go index 56cb4731d..5115f359b 100644 --- a/v2/pkg/variablesvalidation/variablesvalidation.go +++ b/v2/pkg/variablesvalidation/variablesvalidation.go @@ -24,11 +24,35 @@ func (e *InvalidVariableError) Error() string { return e.Message } -func newInvalidVariableError(message string, isApolloCompatibilityMode bool) *InvalidVariableError { +func (v *variablesVisitor) invalidValueIfAllowed(variableContent string) string { + if v.opts.DisableExposingVariablesContent { + return "" + } + + return fmt.Sprintf(": %s", variableContent) +} + +func (v *variablesVisitor) invalidEnumValueIfAllowed(variableContent string) string { + if v.opts.DisableExposingVariablesContent { + return "" + } + + return fmt.Sprintf("\"%s\" ", variableContent) +} + +func (v *variablesVisitor) invalidValueMessage(variableName, variableContent string) string { + if v.opts.DisableExposingVariablesContent { + return fmt.Sprintf(`Variable "$%s" got invalid value`, variableName) + } + + return fmt.Sprintf(`Variable "$%s" got invalid value %s`, variableName, variableContent) +} + +func (v *variablesVisitor) newInvalidVariableError(message string) *InvalidVariableError { err := &InvalidVariableError{ Message: message, } - if isApolloCompatibilityMode { + if v.opts.ApolloCompatibilityFlags.ReplaceInvalidVarError { err.ExtensionCode = errorcodes.BadUserInput } return err @@ -40,16 +64,16 @@ type VariablesValidator struct { } type VariablesValidatorOptions struct { - ApolloCompatibilityFlags apollocompatibility.Flags + ApolloCompatibilityFlags apollocompatibility.Flags + DisableExposingVariablesContent bool } func NewVariablesValidator(options VariablesValidatorOptions) *VariablesValidator { walker := astvisitor.NewWalker(8) visitor := &variablesVisitor{ - variables: &astjson.JSON{}, - walker: &walker, - apolloCompatibilityFlags: options.ApolloCompatibilityFlags, - dev_mode: false, + variables: &astjson.JSON{}, + walker: &walker, + opts: options, } walker.RegisterEnterVariableDefinitionVisitor(visitor) return &VariablesValidator{ @@ -58,11 +82,8 @@ func NewVariablesValidator(options VariablesValidatorOptions) *VariablesValidato } } -func (v *VariablesValidator) Validate(operation, definition *ast.Document, variables []byte, devMode bool) error { +func (v *VariablesValidator) Validate(operation, definition *ast.Document, variables []byte) error { v.visitor.err = nil - if devMode { - v.visitor.dev_mode = devMode - } v.visitor.definition = definition v.visitor.operation = operation err := v.visitor.variables.ParseObject(variables) @@ -86,8 +107,7 @@ type variablesVisitor struct { currentVariableName []byte currentVariableJsonNodeRef int path []pathItem - dev_mode bool - apolloCompatibilityFlags apollocompatibility.Flags + opts VariablesValidatorOptions } func (v *variablesVisitor) renderPath() string { @@ -195,10 +215,7 @@ func (v *variablesVisitor) renderVariableRequiredError(variableName []byte, type v.err = err return } - v.err = newInvalidVariableError( - fmt.Sprintf(`Variable "$%s" of required type "%s" was not provided.`, string(variableName), out.String()), - v.apolloCompatibilityFlags.ReplaceInvalidVarError, - ) + v.err = v.newInvalidVariableError(fmt.Sprintf(`Variable "$%s" of required type "%s" was not provided.`, string(variableName), out.String())) } func (v *variablesVisitor) renderVariableInvalidObjectTypeError(typeName []byte, variablesNode astjson.Node) { @@ -209,17 +226,7 @@ func (v *variablesVisitor) renderVariableInvalidObjectTypeError(typeName []byte, return } variableContent := out.String() - if v.dev_mode { - v.err = newInvalidVariableError( - fmt.Sprintf(`Variable "$%s" got invalid value %s; Expected type "%s" to be an object.`, string(v.currentVariableName), variableContent, string(typeName)), - v.apolloCompatibilityFlags.ReplaceInvalidVarError, - ) - } else { - v.err = newInvalidVariableError( - fmt.Sprintf(`Variable "$%s" got invalid value; Expected type "%s" to be an object.`, string(v.currentVariableName), string(typeName)), - v.apolloCompatibilityFlags.ReplaceInvalidVarError, - ) - } + v.err = v.newInvalidVariableError(fmt.Sprintf(`%s; Expected type "%s" to be an object.`, v.invalidValueMessage(string(v.currentVariableName), variableContent), string(typeName))) } func (v *variablesVisitor) renderVariableRequiredNotProvidedError(fieldName []byte, typeRef int) { @@ -236,17 +243,7 @@ func (v *variablesVisitor) renderVariableRequiredNotProvidedError(fieldName []by v.err = err return } - if v.dev_mode { - v.err = newInvalidVariableError( - fmt.Sprintf(`Variable "$%s" got invalid value %s; Field "%s" of required type "%s" was not provided.`, string(v.currentVariableName), variableContent, string(fieldName), out.String()), - v.apolloCompatibilityFlags.ReplaceInvalidVarError, - ) - } else { - v.err = newInvalidVariableError( - fmt.Sprintf(`Variable "$%s" got invalid value; Field "%s" of required type "%s" was not provided.`, string(v.currentVariableName), string(fieldName), out.String()), - v.apolloCompatibilityFlags.ReplaceInvalidVarError, - ) - } + v.err = v.newInvalidVariableError(fmt.Sprintf(`%s; Field "%s" of required type "%s" was not provided.`, v.invalidValueMessage(string(v.currentVariableName), variableContent), string(fieldName), out.String())) } func (v *variablesVisitor) renderVariableInvalidNestedTypeError(actualJsonNodeRef int, expectedType ast.NodeKind, expectedTypeName []byte, expectedList bool) { @@ -267,116 +264,26 @@ func (v *variablesVisitor) renderVariableInvalidNestedTypeError(actualJsonNodeRe case ast.NodeKindScalarTypeDefinition: switch typeName { case "String": - if v.dev_mode { - v.err = newInvalidVariableError( - fmt.Sprintf(`Variable "$%s" got invalid value %s%s; String cannot represent a non string value: %s`, variableName, invalidValue, path, invalidValue), - v.apolloCompatibilityFlags.ReplaceInvalidVarError, - ) - } else { - v.err = newInvalidVariableError( - fmt.Sprintf(`Variable "$%s" got invalid value%s; String cannot represent a non string value`, variableName, path), - v.apolloCompatibilityFlags.ReplaceInvalidVarError, - ) - } + v.err = v.newInvalidVariableError(fmt.Sprintf(`%s%s; String cannot represent a non string value%s`, v.invalidValueMessage(variableName, invalidValue), path, v.invalidValueIfAllowed(invalidValue))) case "Int": - if v.dev_mode { - v.err = newInvalidVariableError( - fmt.Sprintf(`Variable "$%s" got invalid value %s%s; Int cannot represent non-integer value: %s`, variableName, invalidValue, path, invalidValue), - v.apolloCompatibilityFlags.ReplaceInvalidVarError, - ) - } else { - v.err = newInvalidVariableError( - fmt.Sprintf(`Variable "$%s" got invalid value%s; Int cannot represent non-integer value`, variableName, path), - v.apolloCompatibilityFlags.ReplaceInvalidVarError, - ) - } + v.err = v.newInvalidVariableError(fmt.Sprintf(`%s%s; Int cannot represent non-integer value%s`, v.invalidValueMessage(variableName, invalidValue), path, v.invalidValueIfAllowed(invalidValue))) case "Float": - if v.dev_mode { - v.err = newInvalidVariableError( - fmt.Sprintf(`Variable "$%s" got invalid value %s%s; Float cannot represent non numeric value: %s`, variableName, invalidValue, path, invalidValue), - v.apolloCompatibilityFlags.ReplaceInvalidVarError, - ) - } else { - v.err = newInvalidVariableError( - fmt.Sprintf(`Variable "$%s" got invalid value%s; Float cannot represent non numeric value`, variableName, path), - v.apolloCompatibilityFlags.ReplaceInvalidVarError, - ) - } + v.err = v.newInvalidVariableError(fmt.Sprintf(`%s%s; Float cannot represent non numeric value%s`, v.invalidValueMessage(variableName, invalidValue), path, v.invalidValueIfAllowed(invalidValue))) case "Boolean": - if v.dev_mode { - v.err = newInvalidVariableError( - fmt.Sprintf(`Variable "$%s" got invalid value %s%s; Boolean cannot represent a non boolean value: %s`, variableName, invalidValue, path, invalidValue), - v.apolloCompatibilityFlags.ReplaceInvalidVarError, - ) - } else { - v.err = newInvalidVariableError( - fmt.Sprintf(`Variable "$%s" got invalid value%s; Boolean cannot represent a non boolean value`, variableName, path), - v.apolloCompatibilityFlags.ReplaceInvalidVarError, - ) - } + v.err = v.newInvalidVariableError(fmt.Sprintf(`%s%s; Boolean cannot represent a non boolean value%s`, v.invalidValueMessage(variableName, invalidValue), path, v.invalidValueIfAllowed(invalidValue))) case "ID": - if v.dev_mode { - v.err = newInvalidVariableError( - fmt.Sprintf(`Variable "$%s" got invalid value %s%s; ID cannot represent value: %s`, variableName, invalidValue, path, invalidValue), - v.apolloCompatibilityFlags.ReplaceInvalidVarError, - ) - } else { - v.err = newInvalidVariableError( - fmt.Sprintf(`Variable "$%s" got invalid value%s; ID cannot represent value`, variableName, path), - v.apolloCompatibilityFlags.ReplaceInvalidVarError, - ) - } + v.err = v.newInvalidVariableError(fmt.Sprintf(`%s%s; ID cannot represent a non-string and non-integer value%s`, v.invalidValueMessage(variableName, invalidValue), path, v.invalidValueIfAllowed(invalidValue))) default: - if v.dev_mode { - v.err = newInvalidVariableError( - fmt.Sprintf(`Variable "$%s" got invalid value %s%s; Expected type "%s" to be a scalar.`, variableName, invalidValue, path, typeName), - v.apolloCompatibilityFlags.ReplaceInvalidVarError, - ) - } else { - v.err = newInvalidVariableError( - fmt.Sprintf(`Variable "$%s" got invalid value%s; Expected type "%s" to be a scalar.`, variableName, path, typeName), - v.apolloCompatibilityFlags.ReplaceInvalidVarError, - ) - } + v.err = v.newInvalidVariableError(fmt.Sprintf(`%s%s; Expected type "%s" to be a scalar.`, v.invalidValueMessage(variableName, invalidValue), path, typeName)) } case ast.NodeKindInputObjectTypeDefinition: if expectedList { - if v.dev_mode { - v.err = newInvalidVariableError( - fmt.Sprintf(`Variable "$%s" got invalid value %s%s; Got input type "%s", want: "[%s]"`, variableName, invalidValue, path, typeName, typeName), - v.apolloCompatibilityFlags.ReplaceInvalidVarError, - ) - } else { - v.err = newInvalidVariableError( - fmt.Sprintf(`Variable "$%s" got invalid value%s; Got input type "%s", want: "[%s]"`, variableName, path, typeName, typeName), - v.apolloCompatibilityFlags.ReplaceInvalidVarError, - ) - } + v.err = v.newInvalidVariableError(fmt.Sprintf(`%s%s; Got input type "%s", want: "[%s]"`, v.invalidValueMessage(variableName, invalidValue), path, typeName, typeName)) } else { - if v.dev_mode { - v.err = newInvalidVariableError( - fmt.Sprintf(`Variable "$%s" got invalid value %s%s; Expected type "%s" to be an input object.`, variableName, invalidValue, path, typeName), - v.apolloCompatibilityFlags.ReplaceInvalidVarError, - ) - } else { - v.err = newInvalidVariableError( - fmt.Sprintf(`Variable "$%s" got invalid value%s; Expected type "%s" to be an input object.`, variableName, path, typeName), - v.apolloCompatibilityFlags.ReplaceInvalidVarError, - ) - } + v.err = v.newInvalidVariableError(fmt.Sprintf(`%s%s; Expected type "%s" to be an input object.`, v.invalidValueMessage(variableName, invalidValue), path, typeName)) } case ast.NodeKindEnumTypeDefinition: - if v.dev_mode { - v.err = newInvalidVariableError( - fmt.Sprintf(`Variable "$%s" got invalid value %s%s; Enum "%s" cannot represent non-string value: %s.`, variableName, invalidValue, path, typeName, invalidValue), - v.apolloCompatibilityFlags.ReplaceInvalidVarError, - ) - } else { - v.err = newInvalidVariableError( - fmt.Sprintf(`Variable "$%s" got invalid value%s; Enum "%s" cannot represent non-string value.`, variableName, path, typeName), - v.apolloCompatibilityFlags.ReplaceInvalidVarError, - ) - } + v.err = v.newInvalidVariableError(fmt.Sprintf(`%s%s; Enum "%s" cannot represent non-string value%s.`, v.invalidValueMessage(variableName, invalidValue), path, typeName, v.invalidValueIfAllowed(invalidValue))) } } @@ -390,17 +297,7 @@ func (v *variablesVisitor) renderVariableFieldNotDefinedError(fieldName []byte, } invalidValue := buf.String() path := v.renderPath() - if v.dev_mode { - v.err = newInvalidVariableError( - fmt.Sprintf(`Variable "$%s" got invalid value %s at "%s"; Field "%s" is not defined by type "%s".`, variableName, invalidValue, path, string(fieldName), string(typeName)), - v.apolloCompatibilityFlags.ReplaceInvalidVarError, - ) - } else { - v.err = newInvalidVariableError( - fmt.Sprintf(`Variable "$%s" got invalid value at "%s"; Field "%s" is not defined by type "%s".`, variableName, path, string(fieldName), string(typeName)), - v.apolloCompatibilityFlags.ReplaceInvalidVarError, - ) - } + v.err = v.newInvalidVariableError(fmt.Sprintf(`%s at "%s"; Field "%s" is not defined by type "%s".`, v.invalidValueMessage(variableName, invalidValue), path, string(fieldName), string(typeName))) } func (v *variablesVisitor) renderVariableEnumValueDoesNotExistError(typeName []byte, enumValue []byte) { @@ -416,17 +313,7 @@ func (v *variablesVisitor) renderVariableEnumValueDoesNotExistError(typeName []b if len(v.path) > 1 { path = fmt.Sprintf(` at "%s"`, v.renderPath()) } - if v.dev_mode { - v.err = newInvalidVariableError( - fmt.Sprintf(`Variable "$%s" got invalid value %s%s; Value "%s" does not exist in "%s" enum.`, variableName, invalidValue, path, string(enumValue), string(typeName)), - v.apolloCompatibilityFlags.ReplaceInvalidVarError, - ) - } else { - v.err = newInvalidVariableError( - fmt.Sprintf(`Variable "$%s" got invalid value%s; Value does not exist in "%s" enum.`, variableName, path, string(typeName)), - v.apolloCompatibilityFlags.ReplaceInvalidVarError, - ) - } + v.err = v.newInvalidVariableError(fmt.Sprintf(`%s%s; Value %sdoes not exist in "%s" enum.`, v.invalidValueMessage(variableName, invalidValue), path, v.invalidEnumValueIfAllowed(string(enumValue)), string(typeName))) } func (v *variablesVisitor) renderVariableInvalidNullError(variableName []byte, typeRef int) { @@ -437,10 +324,7 @@ func (v *variablesVisitor) renderVariableInvalidNullError(variableName []byte, t return } typeName := buf.String() - v.err = newInvalidVariableError( - fmt.Sprintf(`Variable "$%s" got invalid value null; Expected non-nullable type "%s" not to be null.`, string(variableName), typeName), - v.apolloCompatibilityFlags.ReplaceInvalidVarError, - ) + v.err = v.newInvalidVariableError(fmt.Sprintf(`Variable "$%s" got invalid value null; Expected non-nullable type "%s" not to be null.`, string(variableName), typeName)) } func (v *variablesVisitor) traverseFieldDefinitionType(fieldTypeDefinitionNodeKind ast.NodeKind, fieldName ast.ByteSlice, typeRef int, fieldVariablesJsonNodeRef int, inputFieldRef int) { diff --git a/v2/pkg/variablesvalidation/variablesvalidation_test.go b/v2/pkg/variablesvalidation/variablesvalidation_test.go index c98ce633a..39a710ed9 100644 --- a/v2/pkg/variablesvalidation/variablesvalidation_test.go +++ b/v2/pkg/variablesvalidation/variablesvalidation_test.go @@ -8,6 +8,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "github.com/wundergraph/graphql-go-tools/v2/pkg/astnormalization" "github.com/wundergraph/graphql-go-tools/v2/pkg/operationreport" @@ -18,1277 +19,1168 @@ import ( func TestVariablesValidation(t *testing.T) { t.Run("required field argument not provided", func(t *testing.T) { - devMode := false tc := testCase{ schema: `type Query { hello(arg: String!): String }`, operation: `query Foo($bar: String!) { hello }`, variables: `{}`, } - err := runTest(t, tc, devMode) + err := runTest(t, tc) require.Error(t, err) assert.Equal(t, `Variable "$bar" of required type "String!" was not provided.`, err.Error()) }) t.Run("a missing required input produces an error", func(t *testing.T) { - devMode := false tc := testCase{ schema: inputSchema, operation: `query Foo($input: SelfSatisfiedInput!) { satisfied }`, variables: `{}`, } - err := runTest(t, tc, devMode) + err := runTest(t, tc) require.Error(t, err) assert.Equal(t, `Variable "$input" of required type "SelfSatisfiedInput!" was not provided.`, err.Error()) }) t.Run("provided required input fields with default values do not produce validation errors", func(t *testing.T) { - devMode := false tc := testCase{ schema: inputSchema, operation: `query Foo($input: SelfSatisfiedInput!) { satisfied(input: $input) }`, variables: `{ "input": { } }`, } - err := runTest(t, tc, devMode) + err := runTest(t, tc) require.NoError(t, err) }) - t.Run("dev_mode unprovided required input fields without default values produce validation errors #1", func(t *testing.T) { - devMode := true + t.Run("unprovided required input fields without default values produce validation errors #1 - with variable content", func(t *testing.T) { tc := testCase{ schema: inputSchema, operation: `query Foo($input: SelfUnsatisfiedInput!) { unsatisfied(input: $input) }`, variables: `{ "input": { } }`, } - err := runTest(t, tc, devMode) + err := runTestWithVariablesContentEnabled(t, tc) require.Error(t, err) assert.Equal(t, `Variable "$input" got invalid value {}; Field "nested" of required type "NestedSelfSatisfiedInput!" was not provided.`, err.Error()) }) t.Run("unprovided required input fields without default values produce validation errors #1", func(t *testing.T) { - devMode := false tc := testCase{ schema: inputSchema, operation: `query Foo($input: SelfUnsatisfiedInput!) { unsatisfied(input: $input) }`, variables: `{ "input": { } }`, } - err := runTest(t, tc, devMode) + err := runTest(t, tc) require.Error(t, err) assert.Equal(t, `Variable "$input" got invalid value; Field "nested" of required type "NestedSelfSatisfiedInput!" was not provided.`, err.Error()) }) - - t.Run("dev_mode unprovided required input fields without default values produce validation errors #2", func(t *testing.T) { - devMode := true + t.Run("unprovided required input fields without default values produce validation errors #2 - with variable content", func(t *testing.T) { tc := testCase{ schema: inputSchema, operation: `query Foo($input: SelfUnsatisfiedInput!) { unsatisfied(input: $input) }`, variables: `{ "input": { "nested": { }, "value": "string" } }`, } - err := runTest(t, tc, devMode) + err := runTestWithVariablesContentEnabled(t, tc) require.Error(t, err) assert.Equal(t, `Variable "$input" got invalid value {"nested":{},"value":"string"}; Field "secondNested" of required type "NestedSelfSatisfiedInput!" was not provided.`, err.Error()) }) t.Run("unprovided required input fields without default values produce validation errors #2", func(t *testing.T) { - devMode := false tc := testCase{ schema: inputSchema, operation: `query Foo($input: SelfUnsatisfiedInput!) { unsatisfied(input: $input) }`, variables: `{ "input": { "nested": { }, "value": "string" } }`, } - err := runTest(t, tc, devMode) + err := runTest(t, tc) require.Error(t, err) assert.Equal(t, `Variable "$input" got invalid value; Field "secondNested" of required type "NestedSelfSatisfiedInput!" was not provided.`, err.Error()) }) t.Run("provided but empty nested required inputs with default values do not produce validation errors", func(t *testing.T) { - devMode := false tc := testCase{ schema: inputSchema, operation: `query Foo($input: SelfUnsatisfiedInput!) { unsatisfied(input: $input) }`, variables: `{ "input": { "nested": { }, "secondNested": { } } }`, } - err := runTest(t, tc, devMode) + err := runTest(t, tc) require.NoError(t, err) }) t.Run("not required field argument not provided", func(t *testing.T) { - devMode := false tc := testCase{ schema: `type Query { hello(arg: String): String }`, operation: `query Foo($bar: String) { hello }`, variables: `{}`, } - err := runTest(t, tc, devMode) + err := runTest(t, tc) require.NoError(t, err) }) t.Run("required field argument provided", func(t *testing.T) { - devMode := false tc := testCase{ schema: `type Query { hello(arg: String!): String }`, operation: `query Foo($bar: String!) { hello(arg: $bar) }`, variables: `{"bar": "world"}`, } - err := runTest(t, tc, devMode) + err := runTest(t, tc) require.NoError(t, err) }) - t.Run("dev_mode nested argument is value instead of list", func(t *testing.T) { - devMode := true + t.Run("nested argument is value instead of list - with variable content", func(t *testing.T) { tc := testCase{ schema: `type Query { hello(input: Input): String } input Input { bar: [String]! }`, operation: `query Foo($input: Input) { hello(input: $input) }`, variables: `{"input":{"bar":"world"}}`, } - err := runTest(t, tc, devMode) + err := runTestWithVariablesContentEnabled(t, tc) require.NotNil(t, err) assert.Equal(t, `Variable "$input" got invalid value "world" at "input.bar"; Got input type "String", want: "[String]"`, err.Error()) }) t.Run("nested argument is value instead of list", func(t *testing.T) { - devMode := false tc := testCase{ schema: `type Query { hello(input: Input): String } input Input { bar: [String]! }`, operation: `query Foo($input: Input) { hello(input: $input) }`, variables: `{"input":{"bar":"world"}}`, } - err := runTest(t, tc, devMode) + err := runTest(t, tc) require.NotNil(t, err) assert.Equal(t, `Variable "$input" got invalid value at "input.bar"; Got input type "String", want: "[String]"`, err.Error()) }) - t.Run("dev_mode nested enum argument is value instead of list", func(t *testing.T) { - devMode := true + t.Run("nested enum argument is value instead of list - with variable content", func(t *testing.T) { tc := testCase{ schema: `type Query { hello(input: Input): String } input Input { bar: [MyNum]! } enum MyNum { ONE TWO }`, operation: `query Foo($input: Input) { hello(input: $input) }`, variables: `{"input":{"bar":"ONE"}}`, } - err := runTest(t, tc, devMode) + err := runTestWithVariablesContentEnabled(t, tc) require.NotNil(t, err) assert.Equal(t, `Variable "$input" got invalid value "ONE" at "input.bar"; Got input type "MyNum", want: "[MyNum]"`, err.Error()) }) t.Run("nested enum argument is value instead of list", func(t *testing.T) { - devMode := false tc := testCase{ schema: `type Query { hello(input: Input): String } input Input { bar: [MyNum]! } enum MyNum { ONE TWO }`, operation: `query Foo($input: Input) { hello(input: $input) }`, variables: `{"input":{"bar":"ONE"}}`, } - err := runTest(t, tc, devMode) + err := runTest(t, tc) require.NotNil(t, err) assert.Equal(t, `Variable "$input" got invalid value at "input.bar"; Got input type "MyNum", want: "[MyNum]"`, err.Error()) }) t.Run("required field argument of custom scalar type not provided", func(t *testing.T) { - devMode := false tc := testCase{ schema: `type Query { hello(arg: Baz!): String } scalar Baz`, operation: `query Foo($bar: Baz!) { hello(arg: $bar) }`, variables: `{}`, } - err := runTest(t, tc, devMode) + err := runTest(t, tc) assert.NotNil(t, err) assert.Equal(t, `Variable "$bar" of required type "Baz!" was not provided.`, err.Error()) }) t.Run("required field argument of custom scalar type was null", func(t *testing.T) { - devMode := false tc := testCase{ schema: `type Query { hello(arg: Baz!): String } scalar Baz`, operation: `query Foo($bar: Baz!) { hello(arg: $bar) }`, variables: `{"bar":null}`, } - err := runTest(t, tc, devMode) + err := runTest(t, tc) assert.NotNil(t, err) assert.Equal(t, `Variable "$bar" got invalid value null; Expected non-nullable type "Baz!" not to be null.`, err.Error()) }) - t.Run("dev_mode required nested field field argument of custom scalar not provided", func(t *testing.T) { - devMode := true + t.Run("required nested field field argument of custom scalar not provided - with variable content", func(t *testing.T) { tc := testCase{ schema: `type Query { hello(arg: Foo!): String } input Foo { bar: Baz! } scalar Baz`, operation: `query Foo($bar: Foo!) { hello(arg: $bar) }`, variables: `{"bar":{}}`, } - err := runTest(t, tc, devMode) + err := runTestWithVariablesContentEnabled(t, tc) assert.NotNil(t, err) assert.Equal(t, `Variable "$bar" got invalid value {}; Field "bar" of required type "Baz!" was not provided.`, err.Error()) }) t.Run("required nested field field argument of custom scalar not provided", func(t *testing.T) { - devMode := false tc := testCase{ schema: `type Query { hello(arg: Foo!): String } input Foo { bar: Baz! } scalar Baz`, operation: `query Foo($bar: Foo!) { hello(arg: $bar) }`, variables: `{"bar":{}}`, } - err := runTest(t, tc, devMode) + err := runTest(t, tc) assert.NotNil(t, err) assert.Equal(t, `Variable "$bar" got invalid value; Field "bar" of required type "Baz!" was not provided.`, err.Error()) }) - t.Run("dev_mode required nested field field argument of custom scalar was null", func(t *testing.T) { - devMode := true + t.Run("required nested field field argument of custom scalar was null - with variable content", func(t *testing.T) { tc := testCase{ schema: `type Query { hello(arg: Foo!): String } input Foo { bar: Baz! } scalar Baz`, operation: `query Foo($bar: Foo!) { hello(arg: $bar) }`, variables: `{"bar":{"bar":null}}`, } - err := runTest(t, tc, devMode) + err := runTestWithVariablesContentEnabled(t, tc) assert.NotNil(t, err) assert.Equal(t, `Variable "$bar" got invalid value {"bar":null}; Field "bar" of required type "Baz!" was not provided.`, err.Error()) }) t.Run("required nested field field argument of custom scalar was null", func(t *testing.T) { - devMode := false tc := testCase{ schema: `type Query { hello(arg: Foo!): String } input Foo { bar: Baz! } scalar Baz`, operation: `query Foo($bar: Foo!) { hello(arg: $bar) }`, variables: `{"bar":{"bar":null}}`, } - err := runTest(t, tc, devMode) + err := runTest(t, tc) assert.NotNil(t, err) assert.Equal(t, `Variable "$bar" got invalid value; Field "bar" of required type "Baz!" was not provided.`, err.Error()) }) t.Run("required field argument provided with default value", func(t *testing.T) { - devMode := false tc := testCase{ schema: `type Query { hello(arg: String!): String }`, operation: `query Foo($bar: String! = "world") { hello(arg: $bar) }`, variables: `{}`, withNormalization: true, } - err := runTest(t, tc, devMode) + err := runTest(t, tc) require.NoError(t, err) }) t.Run("required Int field argument not provided", func(t *testing.T) { - devMode := false tc := testCase{ schema: `type Query { hello(arg: Int!): String }`, operation: `query Foo($bar: Int!) { hello }`, variables: `{}`, } - err := runTest(t, tc, devMode) + err := runTest(t, tc) require.Error(t, err) assert.Equal(t, `Variable "$bar" of required type "Int!" was not provided.`, err.Error()) }) t.Run("required Float field argument not provided", func(t *testing.T) { - devMode := false tc := testCase{ schema: `type Query { hello(arg: Float!): String }`, operation: `query Foo($bar: Float!) { hello }`, variables: `{}`, } - err := runTest(t, tc, devMode) + err := runTest(t, tc) require.Error(t, err) assert.Equal(t, `Variable "$bar" of required type "Float!" was not provided.`, err.Error()) }) t.Run("required Boolean field argument not provided", func(t *testing.T) { - devMode := false tc := testCase{ schema: `type Query { hello(arg: Boolean!): String }`, operation: `query Foo($bar: Boolean!) { hello }`, variables: `{}`, } - err := runTest(t, tc, devMode) + err := runTest(t, tc) require.Error(t, err) assert.Equal(t, `Variable "$bar" of required type "Boolean!" was not provided.`, err.Error()) }) t.Run("required ID field argument not provided", func(t *testing.T) { - devMode := false tc := testCase{ schema: `type Query { hello(arg: ID!): String }`, operation: `query Foo($bar: ID!) { hello }`, variables: `{}`, } - err := runTest(t, tc, devMode) + err := runTest(t, tc) require.Error(t, err) assert.Equal(t, `Variable "$bar" of required type "ID!" was not provided.`, err.Error()) }) t.Run("required ID field argument provided with Int", func(t *testing.T) { - devMode := false tc := testCase{ schema: `type Query { hello(arg: ID!): String }`, operation: `query Foo($bar: ID!) { hello(arg: $bar) }`, variables: `{"bar":123}`, } - err := runTest(t, tc, devMode) + err := runTest(t, tc) require.NoError(t, err) }) t.Run("required ID field argument provided with String", func(t *testing.T) { - devMode := false tc := testCase{ schema: `type Query { hello(arg: ID!): String }`, operation: `query Foo($bar: ID!) { hello(arg: $bar) }`, variables: `{"bar":"hello"}`, } - err := runTest(t, tc, devMode) + err := runTest(t, tc) require.NoError(t, err) }) t.Run("required Enum field argument not provided", func(t *testing.T) { - devMode := false tc := testCase{ schema: `enum Foo { BAR } type Query { hello(arg: Foo!): String }`, operation: `query Foo($bar: Foo!) { hello }`, variables: `{}`, } - err := runTest(t, tc, devMode) + err := runTest(t, tc) require.Error(t, err) assert.Equal(t, `Variable "$bar" of required type "Foo!" was not provided.`, err.Error()) }) t.Run("required input object field argument not provided", func(t *testing.T) { - devMode := false tc := testCase{ schema: `input Foo { bar: String! } type Query { hello(arg: Foo!): String }`, operation: `query Foo($bar: Foo!) { hello }`, variables: `{}`, } - err := runTest(t, tc, devMode) + err := runTest(t, tc) require.Error(t, err) assert.Equal(t, `Variable "$bar" of required type "Foo!" was not provided.`, err.Error()) }) t.Run("required string list field argument not provided", func(t *testing.T) { - devMode := false tc := testCase{ schema: `type Query { hello(arg: [String]!): String }`, operation: `query Foo($bar: [String]!) { hello }`, variables: `{}`, } - err := runTest(t, tc, devMode) + err := runTest(t, tc) require.Error(t, err) assert.Equal(t, `Variable "$bar" of required type "[String]!" was not provided.`, err.Error()) }) - t.Run("dev_mode wrong Boolean value for input object field", func(t *testing.T) { - devMode := true + t.Run("wrong Boolean value for input object field - with variable content", func(t *testing.T) { tc := testCase{ schema: `input Foo { bar: String! } type Query { hello(arg: Foo!): String }`, operation: `query Foo($bar: Foo!) { hello(arg: $bar) }`, variables: `{"bar":true}`, } - err := runTest(t, tc, devMode) + err := runTestWithVariablesContentEnabled(t, tc) require.Error(t, err) assert.Equal(t, `Variable "$bar" got invalid value true; Expected type "Foo" to be an object.`, err.Error()) }) t.Run("wrong Boolean value for input object field", func(t *testing.T) { - devMode := false tc := testCase{ schema: `input Foo { bar: String! } type Query { hello(arg: Foo!): String }`, operation: `query Foo($bar: Foo!) { hello(arg: $bar) }`, variables: `{"bar":true}`, } - err := runTest(t, tc, devMode) + err := runTest(t, tc) require.Error(t, err) assert.Equal(t, `Variable "$bar" got invalid value; Expected type "Foo" to be an object.`, err.Error()) }) - t.Run("dev_mode wrong Integer value for input object field", func(t *testing.T) { - devMode := true + t.Run("wrong Integer value for input object field - with variable content", func(t *testing.T) { tc := testCase{ schema: `input Foo { bar: String! } type Query { hello(arg: Foo!): String }`, operation: `query Foo($bar: Foo!) { hello(arg: $bar) }`, variables: `{"bar":123}`, } - err := runTest(t, tc, devMode) + err := runTestWithVariablesContentEnabled(t, tc) require.Error(t, err) assert.Equal(t, `Variable "$bar" got invalid value 123; Expected type "Foo" to be an object.`, err.Error()) }) t.Run("wrong Integer value for input object field", func(t *testing.T) { - devMode := false tc := testCase{ schema: `input Foo { bar: String! } type Query { hello(arg: Foo!): String }`, operation: `query Foo($bar: Foo!) { hello(arg: $bar) }`, variables: `{"bar":123}`, } - err := runTest(t, tc, devMode) + err := runTest(t, tc) require.Error(t, err) assert.Equal(t, `Variable "$bar" got invalid value; Expected type "Foo" to be an object.`, err.Error()) }) - t.Run("dev_mode required field on present input object not provided", func(t *testing.T) { - devMode := true + t.Run("required field on present input object not provided - with variable content", func(t *testing.T) { tc := testCase{ schema: `input Foo { bar: String! } type Query { hello(arg: Foo!): String }`, operation: `query Foo($bar: Foo!) { hello(arg: $bar) }`, variables: `{"bar":{}}`, } - err := runTest(t, tc, devMode) + err := runTestWithVariablesContentEnabled(t, tc) require.Error(t, err) assert.Equal(t, `Variable "$bar" got invalid value {}; Field "bar" of required type "String!" was not provided.`, err.Error()) }) t.Run("required field on present input object not provided", func(t *testing.T) { - devMode := false tc := testCase{ schema: `input Foo { bar: String! } type Query { hello(arg: Foo!): String }`, operation: `query Foo($bar: Foo!) { hello(arg: $bar) }`, variables: `{"bar":{}}`, } - err := runTest(t, tc, devMode) + err := runTest(t, tc) require.Error(t, err) assert.Equal(t, `Variable "$bar" got invalid value; Field "bar" of required type "String!" was not provided.`, err.Error()) }) t.Run("required field on present input object provided with correct type", func(t *testing.T) { - devMode := false tc := testCase{ schema: `input Foo { bar: String! } type Query { hello(arg: Foo!): String }`, operation: `query Foo($bar: Foo!) { hello(arg: $bar) }`, variables: `{"bar":{"bar":"hello"}}`, } - err := runTest(t, tc, devMode) + err := runTest(t, tc) require.NoError(t, err) }) - t.Run("dev_mode required field on present input object provided with wrong type", func(t *testing.T) { - devMode := true + t.Run("required field on present input object provided with wrong type - with variable content", func(t *testing.T) { tc := testCase{ schema: `input Foo { bar: String! } type Query { hello(arg: Foo!): String }`, operation: `query Foo($input: Foo!) { hello(arg: $input) }`, variables: `{"input":{"bar":123}}`, } - err := runTest(t, tc, devMode) + err := runTestWithVariablesContentEnabled(t, tc) require.Error(t, err) assert.Equal(t, `Variable "$input" got invalid value 123 at "input.bar"; String cannot represent a non string value: 123`, err.Error()) }) t.Run("required field on present input object provided with wrong type", func(t *testing.T) { - devMode := false tc := testCase{ schema: `input Foo { bar: String! } type Query { hello(arg: Foo!): String }`, operation: `query Foo($input: Foo!) { hello(arg: $input) }`, variables: `{"input":{"bar":123}}`, } - err := runTest(t, tc, devMode) + err := runTest(t, tc) require.Error(t, err) assert.Equal(t, `Variable "$input" got invalid value at "input.bar"; String cannot represent a non string value`, err.Error()) }) - t.Run("dev_mode required field on present input object not provided", func(t *testing.T) { - devMode := true + t.Run("required field on present input object not provided - with variable content", func(t *testing.T) { tc := testCase{ schema: `input Foo { bar: String! } type Query { hello(arg: Foo!): String }`, operation: `query Foo($input: Foo!) { hello(arg: $input) }`, variables: `{"input":{}}`, } - err := runTest(t, tc, devMode) + err := runTestWithVariablesContentEnabled(t, tc) require.Error(t, err) assert.Equal(t, `Variable "$input" got invalid value {}; Field "bar" of required type "String!" was not provided.`, err.Error()) }) t.Run("required field on present input object not provided", func(t *testing.T) { - devMode := false tc := testCase{ schema: `input Foo { bar: String! } type Query { hello(arg: Foo!): String }`, operation: `query Foo($input: Foo!) { hello(arg: $input) }`, variables: `{"input":{}}`, } - err := runTest(t, tc, devMode) + err := runTest(t, tc) require.Error(t, err) assert.Equal(t, `Variable "$input" got invalid value; Field "bar" of required type "String!" was not provided.`, err.Error()) }) - t.Run("dev_mode required string field on input object provided with null", func(t *testing.T) { - devMode := true + t.Run("required string field on input object provided with null - with variable content", func(t *testing.T) { tc := testCase{ schema: `input Foo { bar: String! } type Query { hello(arg: Foo!): String }`, operation: `query Foo($input: Foo!) { hello(arg: $input) }`, variables: `{"input":{"bar":null}}`, } - err := runTest(t, tc, devMode) + err := runTestWithVariablesContentEnabled(t, tc) require.Error(t, err) assert.Equal(t, `Variable "$input" got invalid value {"bar":null}; Field "bar" of required type "String!" was not provided.`, err.Error()) }) - + t.Run("required string field on input object provided with null", func(t *testing.T) { - devMode := false tc := testCase{ schema: `input Foo { bar: String! } type Query { hello(arg: Foo!): String }`, operation: `query Foo($input: Foo!) { hello(arg: $input) }`, variables: `{"input":{"bar":null}}`, } - err := runTest(t, tc, devMode) + err := runTest(t, tc) require.Error(t, err) assert.Equal(t, `Variable "$input" got invalid value; Field "bar" of required type "String!" was not provided.`, err.Error()) }) - t.Run("dev_mode required string field on input object provided with Int", func(t *testing.T) { - devMode := true + t.Run("required string field on input object provided with Int - with variable content", func(t *testing.T) { tc := testCase{ schema: `input Foo { bar: String! } type Query { hello(arg: Foo!): String }`, operation: `query Foo($input: Foo!) { hello(arg: $input) }`, variables: `{"input":{"bar":123}}`, } - err := runTest(t, tc, devMode) + err := runTestWithVariablesContentEnabled(t, tc) require.Error(t, err) assert.Equal(t, `Variable "$input" got invalid value 123 at "input.bar"; String cannot represent a non string value: 123`, err.Error()) }) t.Run("required string field on input object provided with Int", func(t *testing.T) { - devMode := false tc := testCase{ schema: `input Foo { bar: String! } type Query { hello(arg: Foo!): String }`, operation: `query Foo($input: Foo!) { hello(arg: $input) }`, variables: `{"input":{"bar":123}}`, } - err := runTest(t, tc, devMode) + err := runTest(t, tc) require.Error(t, err) assert.Equal(t, `Variable "$input" got invalid value at "input.bar"; String cannot represent a non string value`, err.Error()) }) - t.Run("dev_mode required string field on input object provided with Float", func(t *testing.T) { - devMode := true + t.Run("required string field on input object provided with Float - with variable content", func(t *testing.T) { tc := testCase{ schema: `input Foo { bar: String! } type Query { hello(arg: Foo!): String }`, operation: `query Foo($input: Foo!) { hello(arg: $input) }`, variables: `{"input":{"bar":123.456}}`, } - err := runTest(t, tc, devMode) + err := runTestWithVariablesContentEnabled(t, tc) require.Error(t, err) assert.Equal(t, `Variable "$input" got invalid value 123.456 at "input.bar"; String cannot represent a non string value: 123.456`, err.Error()) }) t.Run("required string field on input object provided with Float", func(t *testing.T) { - devMode := false tc := testCase{ schema: `input Foo { bar: String! } type Query { hello(arg: Foo!): String }`, operation: `query Foo($input: Foo!) { hello(arg: $input) }`, variables: `{"input":{"bar":123.456}}`, } - err := runTest(t, tc, devMode) + err := runTest(t, tc) require.Error(t, err) assert.Equal(t, `Variable "$input" got invalid value at "input.bar"; String cannot represent a non string value`, err.Error()) }) - t.Run("dev_mode required string field on input object provided with Boolean", func(t *testing.T) { - devMode := true + t.Run("required string field on input object provided with Boolean - with variable content", func(t *testing.T) { tc := testCase{ schema: `input Foo { bar: String! } type Query { hello(arg: Foo!): String }`, operation: `query Foo($input: Foo!) { hello(arg: $input) }`, variables: `{"input":{"bar":true}}`, } - err := runTest(t, tc, devMode) + err := runTestWithVariablesContentEnabled(t, tc) require.Error(t, err) assert.Equal(t, `Variable "$input" got invalid value true at "input.bar"; String cannot represent a non string value: true`, err.Error()) }) t.Run("required string field on input object provided with Boolean", func(t *testing.T) { - devMode := false tc := testCase{ schema: `input Foo { bar: String! } type Query { hello(arg: Foo!): String }`, operation: `query Foo($input: Foo!) { hello(arg: $input) }`, variables: `{"input":{"bar":true}}`, } - err := runTest(t, tc, devMode) + err := runTest(t, tc) require.Error(t, err) assert.Equal(t, `Variable "$input" got invalid value at "input.bar"; String cannot represent a non string value`, err.Error()) }) - t.Run("dev_mode required string field on nested input object not provided", func(t *testing.T) { - devMode := true + t.Run("required string field on nested input object not provided - with variable content", func(t *testing.T) { tc := testCase{ schema: `input Foo { bar: String! } input Bar { foo: Foo! } type Query { hello(arg: Bar!): String }`, operation: `query Foo($input: Bar!) { hello(arg: $input) }`, variables: `{"input":{"foo":{}}}`, } - err := runTest(t, tc, devMode) + err := runTestWithVariablesContentEnabled(t, tc) require.Error(t, err) assert.Equal(t, `Variable "$input" got invalid value {"foo":{}}; Field "bar" of required type "String!" was not provided.`, err.Error()) }) t.Run("required string field on nested input object not provided", func(t *testing.T) { - devMode := false tc := testCase{ schema: `input Foo { bar: String! } input Bar { foo: Foo! } type Query { hello(arg: Bar!): String }`, operation: `query Foo($input: Bar!) { hello(arg: $input) }`, variables: `{"input":{"foo":{}}}`, } - err := runTest(t, tc, devMode) + err := runTest(t, tc) require.Error(t, err) assert.Equal(t, `Variable "$input" got invalid value; Field "bar" of required type "String!" was not provided.`, err.Error()) }) - t.Run("dev_mode required string field on nested input object provided with null", func(t *testing.T) { - devMode := true + t.Run("required string field on nested input object provided with null - with variable content", func(t *testing.T) { tc := testCase{ schema: `input Foo { bar: String! } input Bar { foo: Foo! } type Query { hello(arg: Bar!): String }`, operation: `query Foo($input: Bar!) { hello(arg: $input) }`, variables: `{"input":{"foo":{"bar":null}}}`, } - err := runTest(t, tc, devMode) + err := runTestWithVariablesContentEnabled(t, tc) require.Error(t, err) assert.Equal(t, `Variable "$input" got invalid value {"foo":{"bar":null}}; Field "bar" of required type "String!" was not provided.`, err.Error()) }) t.Run("required string field on nested input object provided with null", func(t *testing.T) { - devMode := false tc := testCase{ schema: `input Foo { bar: String! } input Bar { foo: Foo! } type Query { hello(arg: Bar!): String }`, operation: `query Foo($input: Bar!) { hello(arg: $input) }`, variables: `{"input":{"foo":{"bar":null}}}`, } - err := runTest(t, tc, devMode) + err := runTest(t, tc) require.Error(t, err) assert.Equal(t, `Variable "$input" got invalid value; Field "bar" of required type "String!" was not provided.`, err.Error()) }) - t.Run("dev_mode required string field on nested input object provided with Int", func(t *testing.T) { - devMode := true + t.Run("required string field on nested input object provided with Int - with variable content", func(t *testing.T) { tc := testCase{ schema: `input Foo { bar: String! } input Bar { foo: Foo! } type Query { hello(arg: Bar!): String }`, operation: `query Foo($input: Bar!) { hello(arg: $input) }`, variables: `{"input":{"foo":{"bar":123}}}`, } - err := runTest(t, tc, devMode) + err := runTestWithVariablesContentEnabled(t, tc) require.Error(t, err) assert.Equal(t, `Variable "$input" got invalid value 123 at "input.foo.bar"; String cannot represent a non string value: 123`, err.Error()) }) t.Run("required string field on nested input object provided with Int", func(t *testing.T) { - devMode := false tc := testCase{ schema: `input Foo { bar: String! } input Bar { foo: Foo! } type Query { hello(arg: Bar!): String }`, operation: `query Foo($input: Bar!) { hello(arg: $input) }`, variables: `{"input":{"foo":{"bar":123}}}`, } - err := runTest(t, tc, devMode) + err := runTest(t, tc) require.Error(t, err) assert.Equal(t, `Variable "$input" got invalid value at "input.foo.bar"; String cannot represent a non string value`, err.Error()) }) - t.Run("dev_mode required string field on nested input object array provided with Int", func(t *testing.T) { - devMode := true + t.Run("required string field on nested input object array provided with Int - with variable content", func(t *testing.T) { tc := testCase{ schema: `input Foo { bar: String! } input Bar { foo: [Foo!]! } type Query { hello(arg: Bar!): String }`, operation: `query Foo($input: Bar!) { hello(arg: $input) }`, variables: `{"input":{"foo":[{"bar":123}]}}`, } - err := runTest(t, tc, devMode) + err := runTestWithVariablesContentEnabled(t, tc) require.Error(t, err) assert.Equal(t, `Variable "$input" got invalid value 123 at "input.foo.[0].bar"; String cannot represent a non string value: 123`, err.Error()) }) t.Run("required string field on nested input object array provided with Int", func(t *testing.T) { - devMode := false tc := testCase{ schema: `input Foo { bar: String! } input Bar { foo: [Foo!]! } type Query { hello(arg: Bar!): String }`, operation: `query Foo($input: Bar!) { hello(arg: $input) }`, variables: `{"input":{"foo":[{"bar":123}]}}`, } - err := runTest(t, tc, devMode) + err := runTest(t, tc) require.Error(t, err) assert.Equal(t, `Variable "$input" got invalid value at "input.foo.[0].bar"; String cannot represent a non string value`, err.Error()) }) - t.Run("dev_mode required string field on nested input object array index 1 provided with Int", func(t *testing.T) { - devMode := true + t.Run("required string field on nested input object array index 1 provided with Int - with variable content", func(t *testing.T) { tc := testCase{ schema: `input Foo { bar: String! } input Bar { foo: [Foo!]! } type Query { hello(arg: Bar!): String }`, operation: `query Foo($input: Bar!) { hello(arg: $input) }`, variables: `{"input":{"foo":[{"bar":"hello"},{"bar":123}]}}`, } - err := runTest(t, tc, devMode) + err := runTestWithVariablesContentEnabled(t, tc) require.Error(t, err) assert.Equal(t, `Variable "$input" got invalid value 123 at "input.foo.[1].bar"; String cannot represent a non string value: 123`, err.Error()) }) t.Run("required string field on nested input object array index 1 provided with Int", func(t *testing.T) { - devMode := false tc := testCase{ schema: `input Foo { bar: String! } input Bar { foo: [Foo!]! } type Query { hello(arg: Bar!): String }`, operation: `query Foo($input: Bar!) { hello(arg: $input) }`, variables: `{"input":{"foo":[{"bar":"hello"},{"bar":123}]}}`, } - err := runTest(t, tc, devMode) + err := runTest(t, tc) require.Error(t, err) assert.Equal(t, `Variable "$input" got invalid value at "input.foo.[1].bar"; String cannot represent a non string value`, err.Error()) }) - t.Run("dev_mode non existing field on nested input object", func(t *testing.T) { - devMode := true + t.Run("non existing field on nested input object - with variable content", func(t *testing.T) { tc := testCase{ schema: `input Foo { bar: String! } input Bar { foo: Foo! } type Query { hello(arg: Bar!): String }`, operation: `query Foo($input: Bar!) { hello(arg: $input) }`, variables: `{"input":{"foo":{"bar":"hello","baz":"world"}}}`, } - err := runTest(t, tc, devMode) + err := runTestWithVariablesContentEnabled(t, tc) require.Error(t, err) assert.Equal(t, `Variable "$input" got invalid value {"foo":{"bar":"hello","baz":"world"}} at "input.foo"; Field "baz" is not defined by type "Foo".`, err.Error()) }) t.Run("non existing field on nested input object", func(t *testing.T) { - devMode := false tc := testCase{ schema: `input Foo { bar: String! } input Bar { foo: Foo! } type Query { hello(arg: Bar!): String }`, operation: `query Foo($input: Bar!) { hello(arg: $input) }`, variables: `{"input":{"foo":{"bar":"hello","baz":"world"}}}`, } - err := runTest(t, tc, devMode) + err := runTest(t, tc) require.Error(t, err) assert.Equal(t, `Variable "$input" got invalid value at "input.foo"; Field "baz" is not defined by type "Foo".`, err.Error()) }) t.Run("required enum argument provided with correct value", func(t *testing.T) { - devMode := false tc := testCase{ schema: `enum Foo { BAR } type Query { hello(arg: Foo!): String }`, operation: `query Foo($bar: Foo!) { hello(arg: $bar) }`, variables: `{"bar":"BAR"}`, } - err := runTest(t, tc, devMode) + err := runTest(t, tc) require.NoError(t, err) }) - t.Run("dev_mode required enum argument provided with wrong value", func(t *testing.T) { - devMode := true + t.Run("required enum argument provided with wrong value - with variable content", func(t *testing.T) { tc := testCase{ schema: `enum Foo { BAR } type Query { hello(arg: Foo!): String }`, operation: `query Foo($bar: Foo!) { hello(arg: $bar) }`, variables: `{"bar":"BAZ"}`, } - err := runTest(t, tc, devMode) + err := runTestWithVariablesContentEnabled(t, tc) require.Error(t, err) assert.Equal(t, `Variable "$bar" got invalid value "BAZ"; Value "BAZ" does not exist in "Foo" enum.`, err.Error()) }) t.Run("required enum argument provided with wrong value", func(t *testing.T) { - devMode := false tc := testCase{ schema: `enum Foo { BAR } type Query { hello(arg: Foo!): String }`, operation: `query Foo($bar: Foo!) { hello(arg: $bar) }`, variables: `{"bar":"BAZ"}`, } - err := runTest(t, tc, devMode) + err := runTest(t, tc) require.Error(t, err) assert.Equal(t, `Variable "$bar" got invalid value; Value does not exist in "Foo" enum.`, err.Error()) }) - t.Run("dev_mode required enum argument provided with Int value", func(t *testing.T) { - devMode := true + t.Run("required enum argument provided with Int value - with variable content", func(t *testing.T) { tc := testCase{ schema: `enum Foo { BAR } type Query { hello(arg: Foo!): String }`, operation: `query Foo($bar: Foo!) { hello(arg: $bar) }`, variables: `{"bar":123}`, } - err := runTest(t, tc, devMode) + err := runTestWithVariablesContentEnabled(t, tc) require.Error(t, err) assert.Equal(t, `Variable "$bar" got invalid value 123; Enum "Foo" cannot represent non-string value: 123.`, err.Error()) }) t.Run("required enum argument provided with Int value", func(t *testing.T) { - devMode := false tc := testCase{ schema: `enum Foo { BAR } type Query { hello(arg: Foo!): String }`, operation: `query Foo($bar: Foo!) { hello(arg: $bar) }`, variables: `{"bar":123}`, } - err := runTest(t, tc, devMode) + err := runTest(t, tc) require.Error(t, err) assert.Equal(t, `Variable "$bar" got invalid value; Enum "Foo" cannot represent non-string value.`, err.Error()) }) t.Run("required enum argument provided with null", func(t *testing.T) { - devMode := false tc := testCase{ schema: `enum Foo { BAR } type Query { hello(arg: Foo!): String }`, operation: `query Foo($bar: Foo!) { hello(arg: $bar) }`, variables: `{"bar":null}`, } - err := runTest(t, tc, devMode) + err := runTest(t, tc) require.Error(t, err) assert.Equal(t, `Variable "$bar" got invalid value null; Expected non-nullable type "Foo!" not to be null.`, err.Error()) }) - t.Run("dev_mode required nested enum argument provided with null", func(t *testing.T) { - devMode := true + t.Run("required nested enum argument provided with null - with variable content", func(t *testing.T) { tc := testCase{ schema: `enum Foo { BAR } input Bar { foo: Foo! } type Query { hello(arg: Bar!): String }`, operation: `query Foo($input: Bar!) { hello(arg: $input) }`, variables: `{"input":{"foo":null}}`, } - err := runTest(t, tc, devMode) + err := runTestWithVariablesContentEnabled(t, tc) require.Error(t, err) assert.Equal(t, `Variable "$input" got invalid value {"foo":null}; Field "foo" of required type "Foo!" was not provided.`, err.Error()) }) t.Run("required nested enum argument provided with null", func(t *testing.T) { - devMode := false tc := testCase{ schema: `enum Foo { BAR } input Bar { foo: Foo! } type Query { hello(arg: Bar!): String }`, operation: `query Foo($input: Bar!) { hello(arg: $input) }`, variables: `{"input":{"foo":null}}`, } - err := runTest(t, tc, devMode) + err := runTest(t, tc) require.Error(t, err) assert.Equal(t, `Variable "$input" got invalid value; Field "foo" of required type "Foo!" was not provided.`, err.Error()) }) t.Run("required nested enum argument provided with correct value", func(t *testing.T) { - devMode := false tc := testCase{ schema: `enum Foo { BAR } input Bar { foo: Foo! } type Query { hello(arg: Bar!): String }`, operation: `query Foo($input: Bar!) { hello(arg: $input) }`, variables: `{"input":{"foo":"BAR"}}`, } - err := runTest(t, tc, devMode) + err := runTest(t, tc) require.NoError(t, err) }) - t.Run("dev_mode required nested enum argument provided with wrong value", func(t *testing.T) { - devMode := true + t.Run("required nested enum argument provided with wrong value - with variable content", func(t *testing.T) { tc := testCase{ schema: `enum Foo { BAR } input Bar { foo: Foo! } type Query { hello(arg: Bar!): String }`, operation: `query Foo($input: Bar!) { hello(arg: $input) }`, variables: `{"input":{"foo":"BAZ"}}`, } - err := runTest(t, tc, devMode) + err := runTestWithVariablesContentEnabled(t, tc) require.Error(t, err) assert.Equal(t, `Variable "$input" got invalid value {"foo":"BAZ"} at "input.foo"; Value "BAZ" does not exist in "Foo" enum.`, err.Error()) }) t.Run("required nested enum argument provided with wrong value", func(t *testing.T) { - devMode := false tc := testCase{ schema: `enum Foo { BAR } input Bar { foo: Foo! } type Query { hello(arg: Bar!): String }`, operation: `query Foo($input: Bar!) { hello(arg: $input) }`, variables: `{"input":{"foo":"BAZ"}}`, } - err := runTest(t, tc, devMode) + err := runTest(t, tc) require.Error(t, err) assert.Equal(t, `Variable "$input" got invalid value at "input.foo"; Value does not exist in "Foo" enum.`, err.Error()) }) t.Run("optional enum argument provided with null", func(t *testing.T) { - devMode := false tc := testCase{ schema: `enum Foo { BAR } type Query { hello(arg: Foo): String }`, operation: `query Foo($bar: Foo) { hello(arg: $bar) }`, variables: `{"bar":null}`, } - err := runTest(t, tc, devMode) + err := runTest(t, tc) require.NoError(t, err) }) t.Run("optional nested enum argument provided with null", func(t *testing.T) { - devMode := false tc := testCase{ schema: `enum Foo { BAR } input Bar { foo: Foo } type Query { hello(arg: Bar): String }`, operation: `query Foo($input: Bar) { hello(arg: $input) }`, variables: `{"input":{"foo":null}}`, } - err := runTest(t, tc, devMode) + err := runTest(t, tc) require.NoError(t, err) }) - t.Run("dev_mode optional nested enum argument provided with incorrect value", func(t *testing.T) { - devMode := true + t.Run("optional nested enum argument provided with incorrect value - with variable content", func(t *testing.T) { tc := testCase{ schema: `enum Foo { BAR } input Bar { foo: Foo } type Query { hello(arg: Bar): String }`, operation: `query Foo($input: Bar) { hello(arg: $input) }`, variables: `{"input":{"foo":"BAZ"}}`, } - err := runTest(t, tc, devMode) + err := runTestWithVariablesContentEnabled(t, tc) require.Error(t, err) assert.Equal(t, `Variable "$input" got invalid value {"foo":"BAZ"} at "input.foo"; Value "BAZ" does not exist in "Foo" enum.`, err.Error()) }) t.Run("optional nested enum argument provided with incorrect value", func(t *testing.T) { - devMode := false tc := testCase{ schema: `enum Foo { BAR } input Bar { foo: Foo } type Query { hello(arg: Bar): String }`, operation: `query Foo($input: Bar) { hello(arg: $input) }`, variables: `{"input":{"foo":"BAZ"}}`, } - err := runTest(t, tc, devMode) + err := runTest(t, tc) require.Error(t, err) assert.Equal(t, `Variable "$input" got invalid value at "input.foo"; Value does not exist in "Foo" enum.`, err.Error()) }) t.Run("optional enum argument provided with correct value", func(t *testing.T) { - devMode := false tc := testCase{ schema: `enum Foo { BAR } type Query { hello(arg: Foo): String }`, operation: `query Foo($bar: Foo) { hello(arg: $bar) }`, variables: `{"bar":"BAR"}`, } - err := runTest(t, tc, devMode) + err := runTest(t, tc) require.NoError(t, err) }) - t.Run("dev_mode optional enum argument provided with wrong value", func(t *testing.T) { - devMode := true + t.Run("optional enum argument provided with wrong value - with variable content", func(t *testing.T) { tc := testCase{ schema: `enum Foo { BAR } type Query { hello(arg: Foo): String }`, operation: `query Foo($bar: Foo) { hello(arg: $bar) }`, variables: `{"bar":"BAZ"}`, } - err := runTest(t, tc, devMode) + err := runTestWithVariablesContentEnabled(t, tc) require.Error(t, err) assert.Equal(t, `Variable "$bar" got invalid value "BAZ"; Value "BAZ" does not exist in "Foo" enum.`, err.Error()) }) t.Run("optional enum argument provided with wrong value", func(t *testing.T) { - devMode := false tc := testCase{ schema: `enum Foo { BAR } type Query { hello(arg: Foo): String }`, operation: `query Foo($bar: Foo) { hello(arg: $bar) }`, variables: `{"bar":"BAZ"}`, } - err := runTest(t, tc, devMode) + err := runTest(t, tc) require.Error(t, err) assert.Equal(t, `Variable "$bar" got invalid value; Value does not exist in "Foo" enum.`, err.Error()) }) t.Run("required string list field argument provided with null", func(t *testing.T) { - devMode := false tc := testCase{ schema: `type Query { hello(arg: [String]!): String }`, operation: `query Foo($bar: [String]!) { hello(arg: $bar) }`, variables: `{"bar":null}`, } - err := runTest(t, tc, devMode) + err := runTest(t, tc) require.Error(t, err) assert.Equal(t, `Variable "$bar" got invalid value null; Expected non-nullable type "[String]!" not to be null.`, err.Error()) }) - t.Run("dev_mode required string list field argument provided with non list Int value", func(t *testing.T) { - devMode := true + t.Run("required string list field argument provided with non list Int value - with variable content", func(t *testing.T) { tc := testCase{ schema: `type Query { hello(arg: [String]!): String }`, operation: `query Foo($bar: [String]!) { hello(arg: $bar) }`, variables: `{"bar":123}`, withNormalization: true, } - err := runTest(t, tc, devMode) + err := runTestWithVariablesContentEnabled(t, tc) require.Error(t, err) assert.Equal(t, `Variable "$bar" got invalid value 123 at "bar.[0]"; String cannot represent a non string value: 123`, err.Error()) }) t.Run("required string list field argument provided with non list Int value", func(t *testing.T) { - devMode := false tc := testCase{ schema: `type Query { hello(arg: [String]!): String }`, operation: `query Foo($bar: [String]!) { hello(arg: $bar) }`, variables: `{"bar":123}`, withNormalization: true, } - err := runTest(t, tc, devMode) + err := runTest(t, tc) require.Error(t, err) assert.Equal(t, `Variable "$bar" got invalid value at "bar.[0]"; String cannot represent a non string value`, err.Error()) }) t.Run("required string argument on input object list provided with correct value", func(t *testing.T) { - devMode := false tc := testCase{ schema: `input Foo { bar: String! } type Query { hello(arg: [Foo!]!): String }`, operation: `query Foo($bar: [Foo!]!) { hello(arg: $bar) }`, variables: `{"bar":[{"bar":"hello"}]}`, } - err := runTest(t, tc, devMode) + err := runTest(t, tc) require.NoError(t, err) }) t.Run("required string argument on input object list provided with wrong value", func(t *testing.T) { - devMode := false tc := testCase{ schema: `input Foo { bar: String! } type Query { hello(arg: [Foo!]!): String }`, operation: `query Foo($bar: [Foo!]!) { hello(arg: $bar) }`, variables: `{"bar":[{"bar":123}]}`, } - err := runTest(t, tc, devMode) + err := runTest(t, tc) require.Error(t, err) assert.Equal(t, `Variable "$bar" got invalid value at "bar.[0].bar"; String cannot represent a non string value`, err.Error()) }) - t.Run("dev_mode required string argument on input object list provided with wrong value", func(t *testing.T) { - devMode := true + t.Run("required string argument on input object list provided with wrong value - with variable content", func(t *testing.T) { tc := testCase{ schema: `input Foo { bar: String! } type Query { hello(arg: [Foo!]!): String }`, operation: `query Foo($bar: [Foo!]!) { hello(arg: $bar) }`, variables: `{"bar":[{"bar":123}]}`, } - err := runTest(t, tc, devMode) + err := runTestWithVariablesContentEnabled(t, tc) require.Error(t, err) assert.Equal(t, `Variable "$bar" got invalid value 123 at "bar.[0].bar"; String cannot represent a non string value: 123`, err.Error()) }) t.Run("required string argument provided with string list", func(t *testing.T) { - devMode := false tc := testCase{ schema: `type Query { hello(arg: String!): String }`, operation: `query Foo($bar: String!) { hello(arg: $bar) }`, variables: `{"bar":["hello"]}`, } - err := runTest(t, tc, devMode) + err := runTest(t, tc) require.Error(t, err) assert.Equal(t, `Variable "$bar" got invalid value; String cannot represent a non string value`, err.Error()) }) - t.Run("dev_mode required input object list field argument provided with non list Int value", func(t *testing.T) { - devMode := true + t.Run("required input object list field argument provided with non list Int value - with variable content", func(t *testing.T) { tc := testCase{ schema: `input Foo { bar: String! } type Query { hello(arg: [Foo!]!): String }`, operation: `query Foo($bar: [Foo!]!) { hello(arg: $bar) }`, variables: `{"bar":123}`, } - err := runTest(t, tc, devMode) + err := runTestWithVariablesContentEnabled(t, tc) require.Error(t, err) assert.Equal(t, `Variable "$bar" got invalid value 123; Expected type "Foo" to be an object.`, err.Error()) }) t.Run("required input object list field argument provided with non list Int value", func(t *testing.T) { - devMode := false tc := testCase{ schema: `input Foo { bar: String! } type Query { hello(arg: [Foo!]!): String }`, operation: `query Foo($bar: [Foo!]!) { hello(arg: $bar) }`, variables: `{"bar":123}`, } - err := runTest(t, tc, devMode) + err := runTest(t, tc) require.Error(t, err) assert.Equal(t, `Variable "$bar" got invalid value; Expected type "Foo" to be an object.`, err.Error()) }) - t.Run("dev_mode required input object field argument provided with list input object value", func(t *testing.T) { - devMode := true + t.Run("required input object field argument provided with list input object value - with variable content", func(t *testing.T) { tc := testCase{ schema: `input Foo { bar: String! } type Query { hello(arg: Foo!): String }`, operation: `query Foo($bar: Foo!) { hello(arg: $bar) }`, variables: `{"bar":[{"bar":"hello"}]}`, } - err := runTest(t, tc, devMode) + err := runTestWithVariablesContentEnabled(t, tc) require.Error(t, err) assert.Equal(t, `Variable "$bar" got invalid value [{"bar":"hello"}]; Expected type "Foo" to be an object.`, err.Error()) }) t.Run("required input object field argument provided with list input object value", func(t *testing.T) { - devMode := false tc := testCase{ schema: `input Foo { bar: String! } type Query { hello(arg: Foo!): String }`, operation: `query Foo($bar: Foo!) { hello(arg: $bar) }`, variables: `{"bar":[{"bar":"hello"}]}`, } - err := runTest(t, tc, devMode) + err := runTest(t, tc) require.Error(t, err) assert.Equal(t, `Variable "$bar" got invalid value; Expected type "Foo" to be an object.`, err.Error()) }) - t.Run("dev_mode required enum list argument provided with non list Int value", func(t *testing.T) { - devMode := true + t.Run("required enum list argument provided with non list Int value - with variable content", func(t *testing.T) { tc := testCase{ schema: `enum Foo { BAR } type Query { hello(arg: [Foo]!): String }`, operation: `query Foo($bar: [Foo]!) { hello(arg: $bar) }`, variables: `{"bar":123}`, withNormalization: true, } - err := runTest(t, tc, devMode) + err := runTestWithVariablesContentEnabled(t, tc) require.Error(t, err) assert.Equal(t, `Variable "$bar" got invalid value 123 at "bar.[0]"; Enum "Foo" cannot represent non-string value: 123.`, err.Error()) }) t.Run("required enum list argument provided with non list Int value", func(t *testing.T) { - devMode := false tc := testCase{ schema: `enum Foo { BAR } type Query { hello(arg: [Foo]!): String }`, operation: `query Foo($bar: [Foo]!) { hello(arg: $bar) }`, variables: `{"bar":123}`, withNormalization: true, } - err := runTest(t, tc, devMode) + err := runTest(t, tc) require.Error(t, err) assert.Equal(t, `Variable "$bar" got invalid value at "bar.[0]"; Enum "Foo" cannot represent non-string value.`, err.Error()) }) - t.Run("dev_mode required string list field argument provided with Int", func(t *testing.T) { - devMode := true + t.Run("required string list field argument provided with Int - with variable content", func(t *testing.T) { tc := testCase{ schema: `type Query { hello(arg: [String]!): String }`, operation: `query Foo($bar: [String]!) { hello(arg: $bar) }`, variables: `{"bar":123}`, withNormalization: true, } - err := runTest(t, tc, devMode) + err := runTestWithVariablesContentEnabled(t, tc) require.Error(t, err) assert.Equal(t, `Variable "$bar" got invalid value 123 at "bar.[0]"; String cannot represent a non string value: 123`, err.Error()) }) t.Run("required string list field argument provided with Int", func(t *testing.T) { - devMode := false tc := testCase{ schema: `type Query { hello(arg: [String]!): String }`, operation: `query Foo($bar: [String]!) { hello(arg: $bar) }`, variables: `{"bar":123}`, withNormalization: true, } - err := runTest(t, tc, devMode) + err := runTest(t, tc) require.Error(t, err) assert.Equal(t, `Variable "$bar" got invalid value at "bar.[0]"; String cannot represent a non string value`, err.Error()) }) t.Run("optional nested list argument provided with null", func(t *testing.T) { - devMode := false tc := testCase{ schema: `input Foo { bars : [String] bat: Int! } type Query { hello(arg: Foo): String }`, operation: `query Foo($input: Foo) { hello(arg: $input) }`, variables: `{"input":{"bars":null,"bat":1}}`, } - err := runTest(t, tc, devMode) + err := runTest(t, tc) require.NoError(t, err) }) t.Run("optional nested list argument provided with empty list", func(t *testing.T) { - devMode := false tc := testCase{ schema: `input Foo { bars : [String] bat: Int! } type Query { hello(arg: Foo): String }`, operation: `query Foo($input: Foo) { hello(arg: $input) }`, variables: `{"input":{"bars":[],"bat":1}}`, } - err := runTest(t, tc, devMode) + err := runTest(t, tc) require.NoError(t, err) }) - t.Run("dev_mode optional nested list argument provided with empty list and missing Int", func(t *testing.T) { - devMode := true + t.Run("optional nested list argument provided with empty list and missing Int - with variable content", func(t *testing.T) { tc := testCase{ schema: `input Foo { bars : [String] bat: Int! } type Query { hello(arg: Foo): String }`, operation: `query Foo($input: Foo) { hello(arg: $input) }`, variables: `{"input":{"bars":[]}}`, } - err := runTest(t, tc, devMode) + err := runTestWithVariablesContentEnabled(t, tc) require.Error(t, err) assert.Equal(t, `Variable "$input" got invalid value {"bars":[]}; Field "bat" of required type "Int!" was not provided.`, err.Error()) }) t.Run("optional nested list argument provided with empty list and missing Int", func(t *testing.T) { - devMode := false tc := testCase{ schema: `input Foo { bars : [String] bat: Int! } type Query { hello(arg: Foo): String }`, operation: `query Foo($input: Foo) { hello(arg: $input) }`, variables: `{"input":{"bars":[]}}`, } - err := runTest(t, tc, devMode) + err := runTest(t, tc) require.Error(t, err) assert.Equal(t, `Variable "$input" got invalid value; Field "bat" of required type "Int!" was not provided.`, err.Error()) }) - t.Run("dev_mode optional nested field is null followed by required nested field of wrong type", func(t *testing.T) { - devMode := true + t.Run("optional nested field is null followed by required nested field of wrong type - with variable content", func(t *testing.T) { tc := testCase{ schema: `input Foo { bar: String! } input Bar { foo: Foo bat: Int! } type Query { hello(arg: Bar): String }`, operation: `query Foo($input: Bar) { hello(arg: $input) }`, variables: `{"input":{"foo":null,"bat":"hello"}}`, } - err := runTest(t, tc, devMode) + err := runTestWithVariablesContentEnabled(t, tc) require.Error(t, err) assert.Equal(t, `Variable "$input" got invalid value "hello" at "input.bat"; Int cannot represent non-integer value: "hello"`, err.Error()) }) t.Run("optional nested field is null followed by required nested field of wrong type", func(t *testing.T) { - devMode := false tc := testCase{ schema: `input Foo { bar: String! } input Bar { foo: Foo bat: Int! } type Query { hello(arg: Bar): String }`, operation: `query Foo($input: Bar) { hello(arg: $input) }`, variables: `{"input":{"foo":null,"bat":"hello"}}`, } - err := runTest(t, tc, devMode) + err := runTest(t, tc) require.Error(t, err) assert.Equal(t, `Variable "$input" got invalid value at "input.bat"; Int cannot represent non-integer value`, err.Error()) }) t.Run("input field is a double nested list", func(t *testing.T) { - devMode := false tc := testCase{ schema: `input Filter { option: String! } input FilterWrapper { filters: [[Filter!]!] } type Query { hello(filter: FilterWrapper): String }`, operation: `query Foo($input: FilterWrapper) { hello(filter: $input) }`, variables: `{"input":{"filters":[[{"option": "a"}]]}}`, } - err := runTest(t, tc, devMode) + err := runTest(t, tc) require.NoError(t, err) }) t.Run("variable of double nested list type", func(t *testing.T) { - devMode := false tc := testCase{ schema: `type Query { hello(filter: [[String]]): String }`, operation: `query Foo($input: [[String]]) { hello(filter: $input) }`, variables: `{"input":[["value"]]}`, } - err := runTest(t, tc, devMode) + err := runTest(t, tc) require.NoError(t, err) }) - t.Run("dev_mode triple nested value into variable of double nested list type", func(t *testing.T) { - devMode := true + t.Run("triple nested value into variable of double nested list type - with variable content", func(t *testing.T) { tc := testCase{ schema: `type Query { hello(filter: [[String]]): String }`, operation: `query Foo($input: [[String]]) { hello(filter: $input) }`, variables: `{"input":[[["value"]]]}`, } - err := runTest(t, tc, devMode) + err := runTestWithVariablesContentEnabled(t, tc) require.Error(t, err) assert.Equal(t, `Variable "$input" got invalid value ["value"] at "input.[0].[0]"; String cannot represent a non string value: ["value"]`, err.Error()) }) t.Run("triple nested value into variable of double nested list type", func(t *testing.T) { - devMode := false tc := testCase{ schema: `type Query { hello(filter: [[String]]): String }`, operation: `query Foo($input: [[String]]) { hello(filter: $input) }`, variables: `{"input":[[["value"]]]}`, } - err := runTest(t, tc, devMode) + err := runTest(t, tc) require.Error(t, err) assert.Equal(t, `Variable "$input" got invalid value at "input.[0].[0]"; String cannot represent a non string value`, err.Error()) }) t.Run("null into non required list value", func(t *testing.T) { - devMode := false tc := testCase{ schema: `type Query { hello(filter: [String]): String }`, operation: `query Foo($input: [String]) { hello(filter: $input) }`, variables: `{"input":[null]}`, } - err := runTest(t, tc, devMode) + err := runTest(t, tc) require.NoError(t, err) }) t.Run("value and null into non required list value", func(t *testing.T) { - devMode := false tc := testCase{ schema: `type Query { hello(filter: [String]): String }`, operation: `query Foo($input: [String]) { hello(filter: $input) }`, variables: `{"input":["ok", null]}`, } - err := runTest(t, tc, devMode) + err := runTest(t, tc) require.NoError(t, err) }) t.Run("null into non required value", func(t *testing.T) { - devMode := false tc := testCase{ schema: `type Query { hello(filter: String): String }`, operation: `query Foo($input: String) { hello(filter: $input) }`, variables: `{"input":null}`, } - err := runTest(t, tc, devMode) + err := runTest(t, tc) require.NoError(t, err) }) t.Run("extension code is propagated with apollo compatibility flag", func(t *testing.T) { - devMode := false tc := testCase{ schema: `type Query { hello(filter: String!): String }`, operation: `query Foo($input: String!) { hello(filter: $input) }`, @@ -1298,7 +1190,7 @@ func TestVariablesValidation(t *testing.T) { ApolloCompatibilityFlags: apollocompatibility.Flags{ ReplaceInvalidVarError: true, }, - }, devMode) + }) assert.Equal(t, &InvalidVariableError{ ExtensionCode: errorcodes.BadUserInput, Message: `Variable "$input" got invalid value null; Expected non-nullable type "String!" not to be null.`, @@ -1311,11 +1203,15 @@ type testCase struct { withNormalization bool } -func runTest(t *testing.T, tc testCase, devMode bool) error { - return runTestWithOptions(t, tc, VariablesValidatorOptions{}, devMode) +func runTest(t *testing.T, tc testCase) error { + return runTestWithOptions(t, tc, VariablesValidatorOptions{DisableExposingVariablesContent: true}) +} + +func runTestWithVariablesContentEnabled(t *testing.T, tc testCase) error { + return runTestWithOptions(t, tc, VariablesValidatorOptions{DisableExposingVariablesContent: false}) } -func runTestWithOptions(t *testing.T, tc testCase, options VariablesValidatorOptions, devMode bool) error { +func runTestWithOptions(t *testing.T, tc testCase, options VariablesValidatorOptions) error { t.Helper() def := unsafeparser.ParseGraphqlDocumentString(tc.schema) op := unsafeparser.ParseGraphqlDocumentString(tc.operation) @@ -1333,7 +1229,7 @@ func runTestWithOptions(t *testing.T, tc testCase, options VariablesValidatorOpt } } validator := NewVariablesValidator(options) - return validator.Validate(&op, &def, op.Input.Variables, devMode) + return validator.Validate(&op, &def, op.Input.Variables) } var inputSchema = `