diff --git a/src/main/kotlin/com/github/pgutkowski/kgraphql/request/Variables.kt b/src/main/kotlin/com/github/pgutkowski/kgraphql/request/Variables.kt index 92ddc1f9..d90e8d23 100644 --- a/src/main/kotlin/com/github/pgutkowski/kgraphql/request/Variables.kt +++ b/src/main/kotlin/com/github/pgutkowski/kgraphql/request/Variables.kt @@ -18,13 +18,13 @@ data class Variables( /** * map and return object of requested class */ - fun get(kClass: KClass, kType: KType, key: String, transform: (value: String) -> Any?): T? { + fun get(kClass: KClass, kType: KType, typeName: String?, key: String, transform: (value: String) -> Any?): T? { val variable = variables?.find { key == it.name } ?: throw IllegalArgumentException("Variable '$key' was not declared for this operation") val isIterable = kClass.isIterable() - validateVariable(typeDefinitionProvider.typeReference(kType), variable) + validateVariable(typeDefinitionProvider.typeReference(kType), typeName, variable) var value = variablesJson.get(kClass, kType, key.substring(1)) if(value == null && variable.defaultValue != null){ @@ -57,9 +57,9 @@ data class Variables( } } - fun validateVariable(expectedType: TypeReference, variable: OperationVariable){ + fun validateVariable(expectedType: TypeReference, expectedTypeName: String?, variable: OperationVariable){ val variableType = variable.type - val invalidName = expectedType.name != variableType.name + val invalidName = (expectedTypeName ?: expectedType.name) != variableType.name val invalidIsList = expectedType.isList != variableType.isList val invalidNullability = !expectedType.isNullable && variableType.isNullable && variable.defaultValue == null val invalidElementNullability = !expectedType.isElementNullable && variableType.isElementNullable diff --git a/src/main/kotlin/com/github/pgutkowski/kgraphql/schema/execution/ArgumentTransformer.kt b/src/main/kotlin/com/github/pgutkowski/kgraphql/schema/execution/ArgumentTransformer.kt index 7635ea98..2748a1d8 100644 --- a/src/main/kotlin/com/github/pgutkowski/kgraphql/schema/execution/ArgumentTransformer.kt +++ b/src/main/kotlin/com/github/pgutkowski/kgraphql/schema/execution/ArgumentTransformer.kt @@ -16,11 +16,12 @@ open class ArgumentTransformer(val schema : DefaultSchema) { fun transformValue(type: Type, value: String, variables: Variables) : Any? { val kType = type.toKType() + val typeName = type.unwrapped().name return when { value.startsWith("$") -> { variables.get ( - kType.jvmErasure, kType, value, { subValue -> transformValue(type, subValue, variables) } + kType.jvmErasure, kType, typeName, value, { subValue -> transformValue(type, subValue, variables) } ) } value == "null" && type.isNullable() -> null diff --git a/src/main/kotlin/com/github/pgutkowski/kgraphql/schema/structure2/SchemaCompilation.kt b/src/main/kotlin/com/github/pgutkowski/kgraphql/schema/structure2/SchemaCompilation.kt index 1d64414b..e8686265 100644 --- a/src/main/kotlin/com/github/pgutkowski/kgraphql/schema/structure2/SchemaCompilation.kt +++ b/src/main/kotlin/com/github/pgutkowski/kgraphql/schema/structure2/SchemaCompilation.kt @@ -72,7 +72,7 @@ class SchemaCompilation( queryTypes = queryTypeProxies + enums + scalars, inputTypes = inputTypeProxies + enums + scalars, - allTypes = queryTypeProxies + inputTypeProxies + enums + scalars, + allTypes = queryTypeProxies.values + inputTypeProxies.values + enums.values + scalars.values, directives = definition.directives.map { handlePartialDirective(it) } ) val schema = DefaultSchema(configuration, model) diff --git a/src/main/kotlin/com/github/pgutkowski/kgraphql/schema/structure2/SchemaModel.kt b/src/main/kotlin/com/github/pgutkowski/kgraphql/schema/structure2/SchemaModel.kt index dfe30b35..acd6a09b 100644 --- a/src/main/kotlin/com/github/pgutkowski/kgraphql/schema/structure2/SchemaModel.kt +++ b/src/main/kotlin/com/github/pgutkowski/kgraphql/schema/structure2/SchemaModel.kt @@ -14,19 +14,19 @@ data class SchemaModel ( val enums: Map>, Type.Enum>>, val scalars : Map, Type.Scalar<*>>, val unions : List, - val allTypes : Map, Type>, + val allTypes : List, val queryTypes: Map, Type>, val inputTypes: Map, Type>, override val directives: List ) : __Schema { - val allTypesByName = allTypes.values.associate { it.name to it } + val allTypesByName = allTypes.associate { it.name to it } val queryTypesByName = queryTypes.values.associate { it.name to it } val inputTypesByName = inputTypes.values.associate { it.name to it } - override val types: List<__Type> = allTypes.values.toList() + override val types: List<__Type> = allTypes.toList() //workaround on the fact that Double and Float are treated as GraphQL Float .filterNot { it is Type.Scalar<*> && it.kClass == Float::class } .filterNot { it.kClass?.findAnnotation() != null } diff --git a/src/test/kotlin/com/github/pgutkowski/kgraphql/integration/BaseSchemaTest.kt b/src/test/kotlin/com/github/pgutkowski/kgraphql/integration/BaseSchemaTest.kt index 8a6075c6..5a60e9b4 100644 --- a/src/test/kotlin/com/github/pgutkowski/kgraphql/integration/BaseSchemaTest.kt +++ b/src/test/kotlin/com/github/pgutkowski/kgraphql/integration/BaseSchemaTest.kt @@ -232,6 +232,18 @@ abstract class BaseSchemaTest { }} } } + + inputType() { + name = "ActorInput" + } + + mutation("createActorWithAliasedInputType") { + description = "create new actor from full fledged ActorInput as input type" + resolver { newActor: Actor -> + createdActors.add(newActor) + newActor + } + } } @After diff --git a/src/test/kotlin/com/github/pgutkowski/kgraphql/integration/MutationTest.kt b/src/test/kotlin/com/github/pgutkowski/kgraphql/integration/MutationTest.kt index 44326bee..cf6f24c6 100644 --- a/src/test/kotlin/com/github/pgutkowski/kgraphql/integration/MutationTest.kt +++ b/src/test/kotlin/com/github/pgutkowski/kgraphql/integration/MutationTest.kt @@ -69,4 +69,12 @@ class MutationTest : BaseSchemaTest() { assertNoErrors(map) assertThat(map.extract>("data/createActor"), equalTo(mapOf("howOld" to testActor.age))) } + + @Test + fun `simple mutation with aliased input type`(){ + val map = execute("mutation(\$newActor: ActorInput!) { createActorWithAliasedInputType(newActor: \$newActor) {name}}", + variables = "{\"newActor\": {\"name\": \"${testActor.name}\", \"age\": ${testActor.age}}}") + assertNoErrors(map) + assertThat(map.extract>("data/createActorWithAliasedInputType"), equalTo(mapOf("name" to testActor.name))) + } } diff --git a/src/test/kotlin/com/github/pgutkowski/kgraphql/schema/SchemaBuilderTest.kt b/src/test/kotlin/com/github/pgutkowski/kgraphql/schema/SchemaBuilderTest.kt index b2b0a89f..2490983f 100644 --- a/src/test/kotlin/com/github/pgutkowski/kgraphql/schema/SchemaBuilderTest.kt +++ b/src/test/kotlin/com/github/pgutkowski/kgraphql/schema/SchemaBuilderTest.kt @@ -21,6 +21,7 @@ import org.hamcrest.CoreMatchers.equalTo import org.hamcrest.CoreMatchers.instanceOf import org.hamcrest.CoreMatchers.notNullValue import org.hamcrest.CoreMatchers.nullValue +import org.hamcrest.CoreMatchers.hasItem import org.hamcrest.MatcherAssert import org.hamcrest.MatcherAssert.assertThat import org.junit.Test @@ -509,4 +510,25 @@ class SchemaBuilderTest { } } } + + @Test + fun `Schema can have same type and input type with different names`(){ + val schema = defaultSchema { + inputType() { + name="TypeAsInput" + } + type() { + name="TypeAsObject" + } + } + + assertThat(schema.typeByKClass(InputOne::class), notNullValue()) + assertThat(schema.inputTypeByKClass(InputOne::class), notNullValue()) + + val introspection = deserialize(schema.execute("{__schema{types{name}}}")) + val types = introspection.extract>>("data/__schema/types") + val names = types.map {it["name"]} + assertThat(names, hasItem("TypeAsInput")) + assertThat(names, hasItem("TypeAsObject")) + } } \ No newline at end of file