Skip to content

Commit

Permalink
Correctly validate optional list in inputs (#1133)
Browse files Browse the repository at this point in the history
  • Loading branch information
darl authored Nov 10, 2021
1 parent ee15775 commit 7cbe359
Show file tree
Hide file tree
Showing 2 changed files with 91 additions and 4 deletions.
6 changes: 6 additions & 0 deletions core/src/main/scala/caliban/validation/ValueValidator.scala
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ object ValueValidator {
IO.foreach_(values)(v =>
validateType(inputType.ofType.getOrElse(inputType), v, context, s"List item in $errorContext")
)
case NullValue =>
IO.unit
case other =>
// handle item as the first item in the list
validateType(inputType.ofType.getOrElse(inputType), other, context, s"List item in $errorContext")
Expand All @@ -73,6 +75,8 @@ object ValueValidator {
.getOrElse(NullValue)
validateType(f.`type`(), value, context, s"Field ${f.name} in $errorContext")
}
case NullValue =>
IO.unit
case _ =>
failValidation(
s"$errorContext has invalid type: $argValue",
Expand All @@ -83,6 +87,8 @@ object ValueValidator {
argValue match {
case EnumValue(value) =>
validateEnum(value, inputType, errorContext)
case NullValue =>
IO.unit
case _ =>
failValidation(
s"$errorContext has invalid type: $argValue",
Expand Down
89 changes: 85 additions & 4 deletions core/src/test/scala/caliban/validation/InputObjectSpec.scala
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
package caliban.validation

import caliban.CalibanError
import caliban.{ CalibanError, GraphQLRequest, InputValue, RootResolver, TestUtils, Value }
import caliban.GraphQL._
import caliban.GraphQLRequest
import caliban.{ InputValue, Value }
import caliban.RootResolver
import zio.test.Assertion._
import zio.test._
import zio.test.environment.TestEnvironment
Expand Down Expand Up @@ -58,6 +55,90 @@ object InputObjectSpec extends DefaultRunnableSpec {
} yield assert(res.errors.headOption)(
isSome((isSubtype[CalibanError.ValidationError](anything)))
)
},
testM("allow null passed to optional enum") {
val query =
"""query QueryName($input: TestInputObjectInput!) {
| query(input: $input)
|}""".stripMargin

case class TestInputObject(enumField: Option[TestUtils.Origin])
case class TestInput(input: TestInputObject)
case class TestOutput(value: String)
case class Query(query: TestInput => String)
val gql = graphQL(RootResolver(Query(_.input.enumField.fold("null")(_.toString))))

for {
int <- gql.interpreter
res <- int.executeRequest(
GraphQLRequest(
query = Some(query),
variables = Some(
Map(
"input" -> InputValue.ObjectValue(
Map("enumField" -> Value.NullValue)
)
)
)
)
)
} yield assert(res.errors)(isEmpty)
},
testM("allow null passed to optional object") {
val query =
"""query QueryName($input: TestInputObjectInput!) {
| query(input: $input)
|}""".stripMargin

case class TestInputObject(obj: Option[TestUtils.Painter])
case class TestInput(input: TestInputObject)
case class TestOutput(value: String)
case class Query(query: TestInput => String)
val gql = graphQL(RootResolver(Query(_.input.obj.fold("null")(_.toString))))

for {
int <- gql.interpreter
res <- int.executeRequest(
GraphQLRequest(
query = Some(query),
variables = Some(
Map(
"input" -> InputValue.ObjectValue(
Map("obj" -> Value.NullValue)
)
)
)
)
)
} yield assert(res.errors)(isEmpty)
},
testM("allow null passed to optional list") {
val query =
"""query QueryName($input: TestInputObjectInput!) {
| query(input: $input)
|}""".stripMargin

case class TestInputObject(list: Option[List[Long]])
case class TestInput(input: TestInputObject)
case class TestOutput(value: String)
case class Query(query: TestInput => String)
val gql = graphQL(RootResolver(Query(_.input.list.fold("null")(_.mkString(",")))))

for {
int <- gql.interpreter
res <- int.executeRequest(
GraphQLRequest(
query = Some(query),
variables = Some(
Map(
"input" -> InputValue.ObjectValue(
Map("list" -> Value.NullValue)
)
)
)
)
)
} yield assert(res.errors)(isEmpty)
}
)
}

0 comments on commit 7cbe359

Please sign in to comment.