From 2c39d454ccf0c9a5d424e06a62c2629d9be6593f Mon Sep 17 00:00:00 2001 From: James Hardwick Date: Tue, 12 Jan 2021 10:49:20 -0600 Subject: [PATCH 1/3] A custom object configuration that exposes #57 Causes all tests to fail due to applicaiton startup issues as a result of Typed attempting to typecast GraphQLOutputType to GraphQLInputType --- .../domain/grails/test/app/Artist.groovy | 17 +++++++++++ .../grails/test/app/GraphQLCustomizer.groovy | 30 +++++++++++++++++++ .../grails/test/app/pogo/Painting.groovy | 10 +++++++ 3 files changed, 57 insertions(+) create mode 100644 examples/grails-test-app/grails-app/domain/grails/test/app/Artist.groovy create mode 100644 examples/grails-test-app/src/main/groovy/grails/test/app/pogo/Painting.groovy diff --git a/examples/grails-test-app/grails-app/domain/grails/test/app/Artist.groovy b/examples/grails-test-app/grails-app/domain/grails/test/app/Artist.groovy new file mode 100644 index 00000000..193f803a --- /dev/null +++ b/examples/grails-test-app/grails-app/domain/grails/test/app/Artist.groovy @@ -0,0 +1,17 @@ +package grails.test.app + +import grails.test.app.pogo.Painting +import org.grails.gorm.graphql.entity.dsl.GraphQLMapping + +class Artist { + + String name + + static graphql = GraphQLMapping.build { + add('paintings', [Painting]) { + dataFetcher { + return new Painting(name: 'test', artistName: 'Picaso', heightCm: 60, widthCm: 120) + } + } + } +} diff --git a/examples/grails-test-app/src/main/groovy/grails/test/app/GraphQLCustomizer.groovy b/examples/grails-test-app/src/main/groovy/grails/test/app/GraphQLCustomizer.groovy index 0023434a..aff8fa4e 100644 --- a/examples/grails-test-app/src/main/groovy/grails/test/app/GraphQLCustomizer.groovy +++ b/examples/grails-test-app/src/main/groovy/grails/test/app/GraphQLCustomizer.groovy @@ -1,5 +1,9 @@ package grails.test.app +import grails.test.app.pogo.Painting +import grails.test.app.pogo.Profile +import graphql.schema.GraphQLObjectType +import graphql.schema.GraphQLOutputType import org.grails.gorm.graphql.binding.manager.GraphQLDataBinderManager import org.grails.gorm.graphql.fetcher.GraphQLDataFetcherType import org.grails.gorm.graphql.interceptor.impl.BaseGraphQLFetcherInterceptor @@ -14,6 +18,9 @@ import org.grails.gorm.graphql.fetcher.impl.EntityDataFetcher import org.grails.gorm.graphql.fetcher.impl.SingleEntityDataFetcher import org.grails.gorm.graphql.fetcher.impl.SoftDeleteEntityDataFetcher import org.grails.gorm.graphql.fetcher.manager.GraphQLDataFetcherManager +import org.grails.gorm.graphql.types.GraphQLTypeManager + +import static graphql.schema.GraphQLFieldDefinition.newFieldDefinition @CompileStatic @@ -57,4 +64,27 @@ class GraphQLCustomizer extends GraphQLPostProcessor { binderManager.registerDataBinder(User, new UserDataBinder()) binderManager.registerDataBinder(Role, new RoleDataBinder()) } + + @Override + void doWith(GraphQLTypeManager typeManager) { + GraphQLOutputType stringType = (GraphQLOutputType)typeManager.getType(String) + GraphQLOutputType intType = (GraphQLOutputType)typeManager.getType(Integer) + GraphQLObjectType.Builder builder = GraphQLObjectType.newObject() + .name('Painting') + .field(newFieldDefinition() + .name('name') + .type(stringType)) + .field(newFieldDefinition() + .name('artistName') + .type(stringType)) + .field(newFieldDefinition() + .name('heightCm') + .type(intType)) + .field(newFieldDefinition() + .name('widthCm') + .type(intType)) + + + typeManager.registerType(Painting, builder.build()) + } } diff --git a/examples/grails-test-app/src/main/groovy/grails/test/app/pogo/Painting.groovy b/examples/grails-test-app/src/main/groovy/grails/test/app/pogo/Painting.groovy new file mode 100644 index 00000000..4370ffea --- /dev/null +++ b/examples/grails-test-app/src/main/groovy/grails/test/app/pogo/Painting.groovy @@ -0,0 +1,10 @@ +package grails.test.app.pogo + +class Painting { + + String name + String artistName + Integer heightCm + Integer widthCm + +} From 0c3c8ad1583b44141d805460bf35c4612bc688cb Mon Sep 17 00:00:00 2001 From: James Hardwick Date: Tue, 12 Jan 2021 10:49:52 -0600 Subject: [PATCH 2/3] The fix...we dont need the typecast here --- .../org/grails/gorm/graphql/entity/dsl/helpers/Typed.groovy | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/main/groovy/org/grails/gorm/graphql/entity/dsl/helpers/Typed.groovy b/core/src/main/groovy/org/grails/gorm/graphql/entity/dsl/helpers/Typed.groovy index 1b892b83..793761f4 100644 --- a/core/src/main/groovy/org/grails/gorm/graphql/entity/dsl/helpers/Typed.groovy +++ b/core/src/main/groovy/org/grails/gorm/graphql/entity/dsl/helpers/Typed.groovy @@ -53,7 +53,7 @@ trait Typed { graphQLType = typeManager.getEnumType(type, nullable) } else if (typeManager.hasType(type)) { - graphQLType = (GraphQLInputType)typeManager.getType(type, nullable) + graphQLType = typeManager.getType(type, nullable) } else { PersistentEntity entity = mappingContext?.getPersistentEntity(type.name) From 7a3109e1d71c72119672d8879c6a814420e1035a Mon Sep 17 00:00:00 2001 From: James Hardwick Date: Tue, 12 Jan 2021 11:12:00 -0600 Subject: [PATCH 3/3] Adds a test to confirm the custom mapped object works as expected --- .../domain/grails/test/app/Artist.groovy | 2 +- .../test/app/ArtistIntegrationSpec.groovy | 50 +++++++++++++++++++ 2 files changed, 51 insertions(+), 1 deletion(-) create mode 100644 examples/grails-test-app/src/integration-test/groovy/grails/test/app/ArtistIntegrationSpec.groovy diff --git a/examples/grails-test-app/grails-app/domain/grails/test/app/Artist.groovy b/examples/grails-test-app/grails-app/domain/grails/test/app/Artist.groovy index 193f803a..607240a7 100644 --- a/examples/grails-test-app/grails-app/domain/grails/test/app/Artist.groovy +++ b/examples/grails-test-app/grails-app/domain/grails/test/app/Artist.groovy @@ -10,7 +10,7 @@ class Artist { static graphql = GraphQLMapping.build { add('paintings', [Painting]) { dataFetcher { - return new Painting(name: 'test', artistName: 'Picaso', heightCm: 60, widthCm: 120) + return [new Painting(name: 'test', artistName: 'Picasso', heightCm: 60, widthCm: 120)] } } } diff --git a/examples/grails-test-app/src/integration-test/groovy/grails/test/app/ArtistIntegrationSpec.groovy b/examples/grails-test-app/src/integration-test/groovy/grails/test/app/ArtistIntegrationSpec.groovy new file mode 100644 index 00000000..abd2dfa0 --- /dev/null +++ b/examples/grails-test-app/src/integration-test/groovy/grails/test/app/ArtistIntegrationSpec.groovy @@ -0,0 +1,50 @@ +package grails.test.app + +import grails.gorm.transactions.Rollback +import grails.testing.mixin.integration.Integration +import org.grails.gorm.graphql.plugin.testing.GraphQLSpec +import org.hibernate.SessionFactory +import spock.lang.Specification + +@Integration +@Rollback +class ArtistIntegrationSpec extends Specification implements GraphQLSpec { + + SessionFactory sessionFactory + + void "test listing artists and paintings"() { + given: + def a = new Artist(name: "Picasso").save(flush: true, failOnError: true) + sessionFactory.currentSession.flush() + sessionFactory.currentSession.transaction.commit() + + when: + def resp = graphQL.graphql(""" + { + artistList { + id + name + paintings { + name + heightCm + widthCm + } + } + } + """) + def json = resp.body() + println json.toString() + def artists = json.data.artistList + def artist = artists[0] + + then: + artists.size() == 1 + artist.id == a.id + artist.name == "Picasso" + artist.paintings.size() == 1 + artist.paintings[0].name == "test" + artist.paintings[0].heightCm == 60 + artist.paintings[0].widthCm == 120 + } + +}