diff --git a/src/main/scala/sangria/execution/Resolver.scala b/src/main/scala/sangria/execution/Resolver.scala index 7476c9f9..9693821a 100644 --- a/src/main/scala/sangria/execution/Resolver.scala +++ b/src/main/scala/sangria/execution/Resolver.scala @@ -1165,7 +1165,7 @@ class Resolver[Ctx]( else Vector(field.name) projectedName.map (name => - ProjectedName(name, loop(path.add(astField, objTpe), field.fieldType, fields, currLevel + 1))) + ProjectedName(name, loop(path.add(astField, objTpe), field.fieldType, fields, currLevel + 1), Args(field, astField))) } .flatten case Failure(_) => Vector.empty diff --git a/src/main/scala/sangria/schema/Context.scala b/src/main/scala/sangria/schema/Context.scala index f3979702..0bf9de28 100644 --- a/src/main/scala/sangria/schema/Context.scala +++ b/src/main/scala/sangria/schema/Context.scala @@ -158,7 +158,7 @@ object Projector { } } -case class ProjectedName(name: String, children: Vector[ProjectedName] = Vector.empty) { +case class ProjectedName(name: String, children: Vector[ProjectedName] = Vector.empty, args: Args = Args.empty) { lazy val asVector = { def loop(name: ProjectedName): Vector[Vector[String]] = Vector(name.name) +: (name.children flatMap loop map (name.name +: _)) diff --git a/src/test/scala/sangria/execution/ProjectorSpec.scala b/src/test/scala/sangria/execution/ProjectorSpec.scala index b7579ccf..192eec34 100644 --- a/src/test/scala/sangria/execution/ProjectorSpec.scala +++ b/src/test/scala/sangria/execution/ProjectorSpec.scala @@ -16,6 +16,9 @@ class ProjectorSpec extends WordSpec with Matchers with FutureResultSupport { case class ProductDefer(productIds: List[String]) extends Deferred[List[Right[String, Product]]] + val IntArgument = Argument("intArg", IntType) + val StringArgument = Argument("stringArg", StringType) + val ProductAttributeType = InterfaceType("ProductAttribute", fields[Unit, (String, Any)]( Field("name", StringType, resolve = _.value._1))) @@ -37,7 +40,7 @@ class ProjectorSpec extends WordSpec with Matchers with FutureResultSupport { Field("relatedProducts", ListType(ProductType), tags = ProjectionName("rp") :: Nil, resolve = Projector(1, (ctx, projected) => projected match { - case Vector(ProjectedName("id", _)) => Value(ctx.value.relatedProductIds map (Left(_))) + case Vector(ProjectedName("id", _, _)) => Value(ctx.value.relatedProductIds map (Left(_))) case _ => ProductDefer(ctx.value.relatedProductIds) })) )) @@ -51,8 +54,11 @@ class ProjectorSpec extends WordSpec with Matchers with FutureResultSupport { Field("typeId", StringType, tags = ProjectionExclude :: Nil, resolve = _ => "product"), Field("masterVariant", VariantType, tags = ProjectionName("master1") :: ProjectionName("master2") :: Nil, + arguments = IntArgument :: Nil, resolve = _.value.right.get.variants.head), - Field("variants", ListType(VariantType), resolve = _.value.right.get.variants.tail) + Field("variants", ListType(VariantType), + arguments = StringArgument :: Nil, + resolve = _.value.right.get.variants.tail) )) val QueryType = ObjectType("Query", fields[Ctx, Unit]( @@ -110,7 +116,7 @@ class ProjectorSpec extends WordSpec with Matchers with FutureResultSupport { projectAll { id typeId - variants { + variants(stringArg: "a") { id attributes { name @@ -122,7 +128,7 @@ class ProjectorSpec extends WordSpec with Matchers with FutureResultSupport { relatedProducts { id typeId - variants { + variants(stringArg: "b") { id } } @@ -131,7 +137,7 @@ class ProjectorSpec extends WordSpec with Matchers with FutureResultSupport { projectOne { id typeId - variants { + variants(stringArg: "c") { id typeId } @@ -195,7 +201,9 @@ class ProjectorSpec extends WordSpec with Matchers with FutureResultSupport { ProjectedName("rp", Vector( ProjectedName("id", Vector.empty), ProjectedName("variants", Vector( - ProjectedName("id", Vector.empty)))))))) + ProjectedName("id", Vector.empty)), + Args(StringArgument :: Nil, Map("stringArg" -> "b")))))), + Args(StringArgument :: Nil, Map("stringArg" -> "a")))) ctx.allProjections.zip(expected).map { case (x, y) => compareUnorderedProjectedNames(x, y) @@ -204,7 +212,8 @@ class ProjectorSpec extends WordSpec with Matchers with FutureResultSupport { ctx.oneLevelprojections should be ( Vector( ProjectedName("id", Vector.empty), - ProjectedName("variants", Vector.empty))) + ProjectedName("variants", Vector.empty, + Args(StringArgument :: Nil, Map("stringArg" -> "c"))))) } "handle multiple projected names" in { @@ -214,10 +223,10 @@ class ProjectorSpec extends WordSpec with Matchers with FutureResultSupport { projectAll { id variantIds - masterVariant { + masterVariant(intArg: 1) { mixed } - variants { + variants(stringArg: "a") { id mixed } @@ -226,10 +235,10 @@ class ProjectorSpec extends WordSpec with Matchers with FutureResultSupport { projectOne { id variantIds - masterVariant { + masterVariant(intArg: 2) { mixed } - variants { + variants(stringArg: "b") { id mixed } @@ -270,26 +279,34 @@ class ProjectorSpec extends WordSpec with Matchers with FutureResultSupport { ProjectedName("id", Vector.empty), ProjectedName("masterVariant.id", Vector.empty), ProjectedName("variants.id", Vector.empty), - ProjectedName("master1", Vector( + ProjectedName("master1", + Vector( ProjectedName("mixed1", Vector.empty), - ProjectedName("mixed2", Vector.empty))), - ProjectedName("master2", Vector( + ProjectedName("mixed2", Vector.empty)), + Args(IntArgument :: Nil, Map("intArg" -> 1))), + ProjectedName("master2", + Vector( ProjectedName("mixed1", Vector.empty), - ProjectedName("mixed2", Vector.empty))), + ProjectedName("mixed2", Vector.empty)), + Args(IntArgument :: Nil, Map("intArg" -> 1))), ProjectedName("variants", Vector( ProjectedName("id", Vector.empty), ProjectedName("mixed1", Vector.empty), - ProjectedName("mixed2", Vector.empty))))) + ProjectedName("mixed2", Vector.empty)), + Args(StringArgument :: Nil, Map("stringArg" -> "a"))))) ctx.oneLevelprojections should be ( Vector( ProjectedName("id", Vector.empty), ProjectedName("masterVariant.id", Vector.empty), ProjectedName("variants.id", Vector.empty), - ProjectedName("master1", Vector.empty), - ProjectedName("master2", Vector.empty), - ProjectedName("variants", Vector.empty))) + ProjectedName("master1", Vector.empty, + Args(IntArgument :: Nil, Map("intArg" -> 2))), + ProjectedName("master2", Vector.empty, + Args(IntArgument :: Nil, Map("intArg" -> 2))), + ProjectedName("variants", Vector.empty, + Args(StringArgument :: Nil, Map("stringArg" -> "b"))))) } } }