Skip to content

Commit

Permalink
Merge pull request #316 from sangria-graphql/more_resolve_tests
Browse files Browse the repository at this point in the history
harden tests
  • Loading branch information
yanns authored May 6, 2024
2 parents 1fbed38 + 864c810 commit e1ddfb7
Showing 1 changed file with 133 additions and 37 deletions.
170 changes: 133 additions & 37 deletions core/src/test/scala/sangria/federation/v2/FederationSpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -299,15 +299,10 @@ class FederationSpec extends AsyncFreeSpec {
}
""")

val args: Json = parse(""" { "representations": [{ "__typename": "State", "id": 1 }] } """)
.getOrElse(Json.Null)

import sangria.marshalling.queryAst.queryAstResultMarshaller

"should succeed on federated unmarshaller" in {

implicit val um = Federation.upgrade(sangria.marshalling.circe.CirceInputUnmarshaller)

val args: Json = parse(""" { "representations": [{ "__typename": "State", "id": 1 }] } """)
.getOrElse(Json.Null)

Expand All @@ -324,9 +319,7 @@ class FederationSpec extends AsyncFreeSpec {
}

"should fail on regular unmarshaller" in {

implicit val um = sangria.marshalling.circe.CirceInputUnmarshaller

val args: Json = parse(""" { "representations": [{ "__typename": "State", "id": 1 }] } """)
.getOrElse(Json.Null)

Expand All @@ -336,10 +329,42 @@ class FederationSpec extends AsyncFreeSpec {
}
}

"should fetch several entities" in {

"should fetch several entities of same type in one call" in {
implicit val um = Federation.upgrade(sangria.marshalling.circe.CirceInputUnmarshaller)
val args: Json = parse("""
{
"representations": [
{ "__typename": "State", "id": 1 },
{ "__typename": "State", "id": 2 },
{ "__typename": "State", "id": 20 },
{ "__typename": "State", "id": 5 }
]
}
""").getOrElse(Json.Null)

Executor
.execute(FederationSpec.Schema.schema, query, variables = args)
.map(QueryRenderer.renderPretty(_) should be("""{
| data: {
| _entities: [{
| id: 1
| value: "mock state 1"
| }, {
| id: 2
| value: "mock state 2"
| }, {
| id: 20
| value: "mock state 20"
| }, {
| id: 5
| value: "mock state 5"
| }]
| }
|}""".stripMargin))
}

"should fetch several entities of different types in one call" in {
implicit val um = Federation.upgrade(sangria.marshalling.circe.CirceInputUnmarshaller)
val args: Json = parse("""
{
"representations": [
Expand All @@ -360,48 +385,105 @@ class FederationSpec extends AsyncFreeSpec {
variables = args,
deferredResolver = FederationSpec.Schema.deferredReviewResolver)
.map(QueryRenderer.renderPretty(_) should be("""{
| data: {
| _entities: [{
| id: 1
| value: "mock state 1"
| }, {
| id: 2
| value: "mock state 2"
| }, {
| id: 2
| value: "mock review 2"
| }, {
| id: 20
| value: "mock state 20"
| }, {
| id: 5
| value: "mock state 5"
| }, {
| id: 1
| value: "mock review 1"
| }]
| }
|}""".stripMargin))
| data: {
| _entities: [{
| id: 1
| value: "mock state 1"
| }, {
| id: 2
| value: "mock state 2"
| }, {
| id: 2
| value: "mock review 2"
| }, {
| id: 20
| value: "mock state 20"
| }, {
| id: 5
| value: "mock state 5"
| }, {
| id: 1
| value: "mock review 1"
| }]
| }
|}""".stripMargin))
}

"handles non found entities" in {
implicit val um = Federation.upgrade(sangria.marshalling.circe.CirceInputUnmarshaller)
val args: Json = parse("""
{
"representations": [
{ "__typename": "State", "id": 1 },
{ "__typename": "State", "id": 42 },
{ "__typename": "State", "id": 20 }
]
}
""").getOrElse(Json.Null)

Executor
.execute(FederationSpec.Schema.schema, query, variables = args)
.map(QueryRenderer.renderPretty(_) should be("""{
| data: {
| _entities: [{
| id: 1
| value: "mock state 1"
| }, null, {
| id: 20
| value: "mock state 20"
| }]
| }
|}""".stripMargin))
}

// "handles entities using same arg" in {
// implicit val um = Federation.upgrade(sangria.marshalling.circe.CirceInputUnmarshaller)
// val args: Json = parse("""
// {
// "representations": [
// { "__typename": "Review", "id": 1 },
// { "__typename": "Review2", "id": 1 },
// { "__typename": "Review2", "id": 2 }
// ]
// }
// """).getOrElse(Json.Null)
//
// Executor
// .execute(FederationSpec.Schema.schema, query, variables = args)
// .map(QueryRenderer.renderPretty(_) should be("""{
// | data: {
// | _entities: [{
// | id: 1
// | value: "mock review 1"
// | }, {
// | id: 1
// | value2: "mock review2 1"
// | }, {
// | id: 2
// | value2: "mock review2 2"
// | }]
// | }
// |}""".stripMargin))
// }
}
}
}

object FederationSpec {
object Schema {
private case class State(id: Int, value: String)
private case class StateArg(id: Int)

private val StateType = ObjectType(
"State",
fields[Unit, State](
Field("id", IntType, resolve = _.value.id),
Field("value", OptionType(StringType), resolve = _.value.value))).withDirective(Key("id"))

private case class StateArg(id: Int)
private implicit val stateArgDecoder: Decoder[Json, StateArg] =
deriveDecoder[StateArg].decodeJson(_)
private val stateResolver = EntityResolver[Any, Json, State, StateArg](
__typeName = "State",
(arg, _) => Some(State(arg.id, s"mock state ${arg.id}")))
(arg, _) => if (arg.id == 42) None else Some(State(arg.id, s"mock state ${arg.id}")))

private case class Review(id: Int, value: String)
private case class DeferredReview(id: Int) extends Deferred[Option[Review]]
Expand All @@ -418,30 +500,44 @@ object FederationSpec {
}
}
val deferredReviewResolver: DeferredReviewResolver = DeferredReviewResolver()
private case class ReviewArg(id: Int)
private val ReviewType = ObjectType(
"Review",
fields[Unit, Review](
Field("id", IntType, resolve = _.value.id),
Field("value", OptionType(StringType), resolve = _.value.value))).withDirective(Key("id"))

private case class ReviewArg(id: Int)
private implicit val reviewArgDecoder: Decoder[Json, ReviewArg] =
deriveDecoder[ReviewArg].decodeJson(_)
private val reviewResolver = EntityResolver[Any, Json, Review, ReviewArg](
__typeName = "Review",
(arg, _) => DeferredValue(DeferredReview(arg.id))
)

private case class Review2(id: Int, value2: String)

private val Review2Type = ObjectType(
"Review2",
fields[Unit, Review2](
Field("id", IntType, resolve = _.value.id),
Field("value2", OptionType(StringType), resolve = _.value.value2))).withDirective(Key("id"))
// review2 uses the same arg as review
private val review2Resolver = EntityResolver[Any, Json, Review2, ReviewArg](
__typeName = Review2Type.name,
(arg, _) => Some(Review2(arg.id, s"mock review2 ${arg.id}")))

private val Query = ObjectType(
"Query",
fields[Unit, Any](
Field(name = "states", fieldType = ListType(StateType), resolve = _ => Nil),
Field(name = "reviews", fieldType = ListType(ReviewType), resolve = _ => Nil)
Field(name = "reviews", fieldType = ListType(ReviewType), resolve = _ => Nil),
Field(name = "reviews2", fieldType = ListType(Review2Type), resolve = _ => Nil)
)
)

val schema: Schema[Any, Any] = Federation.extend(
sangria.schema.Schema(Query),
stateResolver :: reviewResolver :: Nil
List(stateResolver, reviewResolver, review2Resolver)
)
}
}

0 comments on commit e1ddfb7

Please sign in to comment.