diff --git a/tools/src/main/scala/caliban/tools/RemoteSchema.scala b/tools/src/main/scala/caliban/tools/RemoteSchema.scala index 39f8eb60c..4c9da7e18 100644 --- a/tools/src/main/scala/caliban/tools/RemoteSchema.scala +++ b/tools/src/main/scala/caliban/tools/RemoteSchema.scala @@ -147,11 +147,18 @@ object RemoteSchema { private def toInterfaceType( definition: Definition.TypeSystemDefinition.TypeDefinition.InterfaceTypeDefinition, definitions: List[Definition.TypeSystemDefinition.TypeDefinition] - ): __Type = + ): __Type = { + val implementations = definitions.collect { + case t @ ObjectTypeDefinition(description, name, implements, directives, fields) + if implements.map(_.name).toSet.contains(definition.name) => + toObjectType(t, definitions) + } + __Type( kind = __TypeKind.INTERFACE, name = Some(definition.name), description = definition.description, + possibleTypes = Some(implementations), fields = (args: __DeprecatedArgs) => if (definition.fields.nonEmpty) Some( @@ -162,6 +169,7 @@ object RemoteSchema { else None, directives = toDirectives(definition.directives) ) + } private def toInputValue( definition: Definition.TypeSystemDefinition.TypeDefinition.InputValueDefinition, diff --git a/tools/src/test/scala/caliban/tools/RemoteSchemaSpec.scala b/tools/src/test/scala/caliban/tools/RemoteSchemaSpec.scala index 13e4720d2..a7f21604b 100644 --- a/tools/src/test/scala/caliban/tools/RemoteSchemaSpec.scala +++ b/tools/src/test/scala/caliban/tools/RemoteSchemaSpec.scala @@ -7,6 +7,8 @@ import caliban.schema._ import zio._ import zio.test.Assertion._ import zio.test._ +import schema.Annotations._ +import caliban.Macros.gqldoc object RemoteSchemaSpec extends DefaultRunnableSpec { sealed trait EnumType extends Product with Serializable @@ -57,6 +59,39 @@ object RemoteSchemaSpec extends DefaultRunnableSpec { sdl = api.render remoteSDL = remoteAPI.render } yield assert(remoteSDL)(equalTo(sdl)) + }, + testM("properly resolves interface types") { + @GQLInterface + sealed trait Node + + sealed trait Viewer + case class User(id: String, email: String) extends Node with Viewer + case class Superuser(id: String) extends Node with Viewer + + case class Queries( + whoAmI: Node = User("1", "foo@bar.com") + ) + + val api = graphQL(RootResolver(Queries())) + val query = gqldoc(""" + query { + whoAmI { + ...on User { + email + } + ...on Node { + id + } + } + }""") + + for { + introspected <- SchemaLoader.fromCaliban(api).load + remoteSchema <- ZIO.fromOption(RemoteSchema.parseRemoteSchema(introspected)) + remoteAPI <- ZIO.effectTotal(fromRemoteSchema(remoteSchema)) + interpreter <- remoteAPI.interpreter + res <- interpreter.check(query) + } yield assert(res)(isUnit) } )