This is an automated email from the ASF dual-hosted git repository.

danhaywood pushed a commit to branch CAUSEWAY-3676
in repository https://gitbox.apache.org/repos/asf/causeway.git

commit ebf4fcff53030a26a9a29c3ab701fdcdda863bc5
Author: danhaywood <[email protected]>
AuthorDate: Tue Feb 13 17:46:35 2024 +0000

    CAUSEWAY-3676: adds support for enum types
    
    and runs the 'mutating' tests under the same context, avoiding need for 
dirtying
---
 .../model/domain/GqlvActionParamAutoComplete.java  |   2 +-
 .../model/domain/GqlvActionParamDisabled.java      |   3 +-
 .../model/domain/GqlvActionParamHidden.java        |   3 +-
 .../model/domain/GqlvActionParamValidate.java      |   3 +-
 .../graphql/model/domain/GqlvActionValidity.java   |  17 ++-
 .../graphql/model/domain/GqlvMemberDisabled.java   |   3 +-
 .../graphql/model/domain/GqlvMemberHidden.java     |   3 +-
 .../model/domain/GqlvPropertyAutoComplete.java     |   2 +-
 .../graphql/model/domain/GqlvPropertyValidate.java |   3 +-
 .../viewer/graphql/model/domain/TypeNames.java     |   4 +
 .../model/marshallers/ScalarMarshallerObject.java  |  15 ++-
 .../model/registry/GraphQLTypeRegistry.java        |  55 +++++++++-
 .../viewer/graphql/model/types/TypeMapper.java     |   5 +-
 .../graphql/model/types/TypeMapperDefault.java     |  45 +++++---
 .../viewer/test/e2e/query/Admin_IntegTest.java     |   1 -
 .../test/e2e/query/Calculator_IntegTest.java       |   1 -
 .../query/Calculator_IntegTest.next_month._.gql    |   2 +-
 .../test/e2e/query/Department_IntegTest.java       |   1 -
 .../viewer/test/e2e/query/DeptHead_IntegTest.java  |   1 -
 .../viewer/test/e2e/query/Staff_IntegTest.java     |   1 -
 .../DepartmentMutating_IntegTest.java              |  10 --
 .../DeptHeadMutating_IntegTest.java                |  10 --
 .../StaffMutating_IntegTest.java                   |  10 --
 .../query_and_mutations/_Mutating_IntegTest.java   |  50 ---------
 .../test/e2e/scenario/Calculator_IntegTest.java    |   1 -
 .../test/e2e/scenario/Department_IntegTest.java    |   1 -
 .../GqlSchemaQuery_print_IntegTest.java            |   2 +-
 ...GqlSchemaQueryAndMutations_print_IntegTest.java |  44 --------
 viewers/graphql/test/src/test/resources/schema.gql | 114 ++++++++++++++++++---
 .../integration/GraphQlSourceForCauseway.java      |  13 +++
 30 files changed, 236 insertions(+), 189 deletions(-)

diff --git 
a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/GqlvActionParamAutoComplete.java
 
b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/GqlvActionParamAutoComplete.java
index 88aba6c71f..87022bf123 100644
--- 
a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/GqlvActionParamAutoComplete.java
+++ 
b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/GqlvActionParamAutoComplete.java
@@ -70,7 +70,7 @@ package org.apache.causeway.viewer.graphql.model.domain;
              holder.addGqlArguments(holder.getObjectAction(), fieldBuilder, 
TypeMapper.InputContext.AUTOCOMPLETE, holder.getParamNum());
              fieldBuilder.argument(GraphQLArgument.newArgument()
                      .name(SEARCH_PARAM_NAME)
-                     
.type(nonNull(context.typeMapper.scalarTypeFor(String.class))))
+                     
.type(nonNull(context.typeMapper.outputTypeFor(String.class))))
                      .build();
              setField(fieldBuilder.build());
          } else {
diff --git 
a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/GqlvActionParamDisabled.java
 
b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/GqlvActionParamDisabled.java
index b0a5576cd9..e324829774 100644
--- 
a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/GqlvActionParamDisabled.java
+++ 
b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/GqlvActionParamDisabled.java
@@ -35,6 +35,7 @@ import 
org.apache.causeway.viewer.graphql.model.mmproviders.ObjectActionParamete
 import 
org.apache.causeway.viewer.graphql.model.mmproviders.ObjectActionProvider;
 import 
org.apache.causeway.viewer.graphql.model.mmproviders.ObjectSpecificationProvider;
 
+import graphql.schema.GraphQLOutputType;
 import lombok.val;
 import lombok.extern.log4j.Log4j2;
 
@@ -52,7 +53,7 @@ public class GqlvActionParamDisabled extends GqlvAbstract {
 
         val fieldBuilder = newFieldDefinition()
                 .name("disabled")
-                .type(context.typeMapper.scalarTypeFor(String.class));
+                .type((GraphQLOutputType) 
context.typeMapper.outputTypeFor(String.class));
         holder.addGqlArguments(holder.getObjectAction(), fieldBuilder, 
TypeMapper.InputContext.DISABLE, holder.getParamNum()+1);
         setField(fieldBuilder.build());
     }
diff --git 
a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/GqlvActionParamHidden.java
 
b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/GqlvActionParamHidden.java
index 9aadc16136..24524fc935 100644
--- 
a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/GqlvActionParamHidden.java
+++ 
b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/GqlvActionParamHidden.java
@@ -35,6 +35,7 @@ package org.apache.causeway.viewer.graphql.model.domain;
  import 
org.apache.causeway.viewer.graphql.model.mmproviders.ObjectActionProvider;
  import 
org.apache.causeway.viewer.graphql.model.mmproviders.ObjectSpecificationProvider;
 
+ import graphql.schema.GraphQLOutputType;
  import lombok.val;
  import lombok.extern.log4j.Log4j2;
 
@@ -51,7 +52,7 @@ public class GqlvActionParamHidden extends GqlvAbstract {
 
         GraphQLFieldDefinition.Builder fieldBuilder = newFieldDefinition()
                 .name("hidden")
-                .type(context.typeMapper.scalarTypeFor(boolean.class));
+                .type((GraphQLOutputType) 
context.typeMapper.outputTypeFor(boolean.class));
         holder.addGqlArguments(holder.getObjectAction(), fieldBuilder, 
TypeMapper.InputContext.DISABLE, holder.getParamNum());
         setField(fieldBuilder.build());
     }
diff --git 
a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/GqlvActionParamValidate.java
 
b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/GqlvActionParamValidate.java
index 6741e39e86..3043f7570e 100644
--- 
a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/GqlvActionParamValidate.java
+++ 
b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/GqlvActionParamValidate.java
@@ -35,6 +35,7 @@ import 
org.apache.causeway.viewer.graphql.model.mmproviders.ObjectActionParamete
 import 
org.apache.causeway.viewer.graphql.model.mmproviders.ObjectActionProvider;
 import 
org.apache.causeway.viewer.graphql.model.mmproviders.ObjectSpecificationProvider;
 
+import graphql.schema.GraphQLOutputType;
 import lombok.val;
 import lombok.extern.log4j.Log4j2;
 
@@ -51,7 +52,7 @@ public class GqlvActionParamValidate extends GqlvAbstract {
 
         val fieldBuilder = newFieldDefinition()
                 .name("validity")
-                .type(context.typeMapper.scalarTypeFor(String.class));
+                .type((GraphQLOutputType) 
context.typeMapper.outputTypeFor(String.class));
         holder.addGqlArgument(holder.getObjectAction(), fieldBuilder, 
TypeMapper.InputContext.DISABLE, holder.getParamNum());
         setField(fieldBuilder.build());
     }
diff --git 
a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/GqlvActionValidity.java
 
b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/GqlvActionValidity.java
index 6db35e8154..c33847e1cc 100644
--- 
a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/GqlvActionValidity.java
+++ 
b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/GqlvActionValidity.java
@@ -55,17 +55,12 @@ public class GqlvActionValidity extends GqlvAbstract {
 
         val objectAction = holder.getObjectAction();
 
-        GraphQLOutputType type = 
this.context.typeMapper.scalarTypeFor(String.class);
-        if (type != null) {
-            val fieldBuilder = newFieldDefinition()
-                    .name("validate")
-                    .type(type);
-
-            holder.addGqlArguments(objectAction, fieldBuilder, 
TypeMapper.InputContext.VALIDATE, objectAction.getParameterCount());
-            setField(fieldBuilder.build());
-        } else {
-            setField(null);
-        }
+        val fieldBuilder = newFieldDefinition()
+                .name("validate")
+                .type((GraphQLOutputType) 
this.context.typeMapper.outputTypeFor(String.class));
+
+        holder.addGqlArguments(objectAction, fieldBuilder, 
TypeMapper.InputContext.VALIDATE, objectAction.getParameterCount());
+        setField(fieldBuilder.build());
     }
 
     @Override
diff --git 
a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/GqlvMemberDisabled.java
 
b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/GqlvMemberDisabled.java
index 4f21701b57..b4ca62fac5 100644
--- 
a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/GqlvMemberDisabled.java
+++ 
b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/GqlvMemberDisabled.java
@@ -31,6 +31,7 @@ import 
org.apache.causeway.viewer.graphql.model.fetcher.BookmarkedPojo;
 import 
org.apache.causeway.viewer.graphql.model.mmproviders.ObjectMemberProvider;
 import 
org.apache.causeway.viewer.graphql.model.mmproviders.ObjectSpecificationProvider;
 
+import graphql.schema.GraphQLOutputType;
 import lombok.val;
 import lombok.extern.log4j.Log4j2;
 
@@ -48,7 +49,7 @@ public class GqlvMemberDisabled<T extends ObjectMember> 
extends GqlvAbstract {
 
         setField(newFieldDefinition()
                 .name("disabled")
-                .type(context.typeMapper.scalarTypeFor(String.class))
+                .type((GraphQLOutputType) 
context.typeMapper.outputTypeFor(String.class))
                 .build());
     }
 
diff --git 
a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/GqlvMemberHidden.java
 
b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/GqlvMemberHidden.java
index d8b0098df3..808a61d130 100644
--- 
a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/GqlvMemberHidden.java
+++ 
b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/GqlvMemberHidden.java
@@ -31,6 +31,7 @@ import 
org.apache.causeway.viewer.graphql.model.fetcher.BookmarkedPojo;
 import 
org.apache.causeway.viewer.graphql.model.mmproviders.ObjectMemberProvider;
 import 
org.apache.causeway.viewer.graphql.model.mmproviders.ObjectSpecificationProvider;
 
+import graphql.schema.GraphQLOutputType;
 import lombok.val;
 import lombok.extern.log4j.Log4j2;
 
@@ -48,7 +49,7 @@ public class GqlvMemberHidden<T extends ObjectMember> extends 
GqlvAbstract {
 
         setField(newFieldDefinition()
                 .name("hidden")
-                .type(this.context.typeMapper.scalarTypeFor(boolean.class))
+                .type((GraphQLOutputType) 
this.context.typeMapper.outputTypeFor(boolean.class))
                 .build());
     }
 
diff --git 
a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/GqlvPropertyAutoComplete.java
 
b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/GqlvPropertyAutoComplete.java
index 8be5f08ecb..5fc36f80bb 100644
--- 
a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/GqlvPropertyAutoComplete.java
+++ 
b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/GqlvPropertyAutoComplete.java
@@ -56,7 +56,7 @@ public class GqlvPropertyAutoComplete extends GqlvAbstract {
                     
.type(GraphQLList.list(context.typeMapper.outputTypeFor(elementType)));
             fieldBuilder.argument(GraphQLArgument.newArgument()
                             .name(SEARCH_PARAM_NAME)
-                            
.type(nonNull(context.typeMapper.scalarTypeFor(String.class))))
+                            
.type(nonNull(context.typeMapper.outputTypeFor(String.class))))
                     .build();
             setField(fieldBuilder.build());
         } else {
diff --git 
a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/GqlvPropertyValidate.java
 
b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/GqlvPropertyValidate.java
index eaeee3d1db..ce6f42ad22 100644
--- 
a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/GqlvPropertyValidate.java
+++ 
b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/GqlvPropertyValidate.java
@@ -32,6 +32,7 @@ import 
org.apache.causeway.viewer.graphql.model.fetcher.BookmarkedPojo;
 import 
org.apache.causeway.viewer.graphql.model.mmproviders.ObjectSpecificationProvider;
 import 
org.apache.causeway.viewer.graphql.model.mmproviders.OneToOneAssociationProvider;
 
+import graphql.schema.GraphQLOutputType;
 import lombok.val;
 
 public class GqlvPropertyValidate extends GqlvAbstract {
@@ -46,7 +47,7 @@ public class GqlvPropertyValidate extends GqlvAbstract {
 
         val fieldBuilder = newFieldDefinition()
                 .name("validate")
-                .type(context.typeMapper.scalarTypeFor(String.class));
+                .type((GraphQLOutputType) 
context.typeMapper.outputTypeFor(String.class));
         holder.addGqlArgument(holder.getOneToOneAssociation(), fieldBuilder, 
TypeMapper.InputContext.VALIDATE);
 
         setField(fieldBuilder.build());
diff --git 
a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/TypeNames.java
 
b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/TypeNames.java
index c824bd5a7c..ca90a3f5b2 100644
--- 
a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/TypeNames.java
+++ 
b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/TypeNames.java
@@ -41,6 +41,10 @@ public final class TypeNames {
         return objectTypeNameFor(objectSpecification) + "__gqlv_input";
     }
 
+    public static String enumTypeNameFor(ObjectSpecification objectSpec) {
+        return objectTypeNameFor(objectSpec) + "__gqlv_enum";
+    }
+
     public static String actionTypeNameFor(ObjectSpecification owningType, 
ObjectAction objectAction) {
         return objectTypeNameFor(owningType) + "__" + objectAction.getId() + 
"__gqlv_action";
     }
diff --git 
a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/marshallers/ScalarMarshallerObject.java
 
b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/marshallers/ScalarMarshallerObject.java
index 82ba8ecf7d..22498e091d 100644
--- 
a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/marshallers/ScalarMarshallerObject.java
+++ 
b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/marshallers/ScalarMarshallerObject.java
@@ -20,14 +20,23 @@ package 
org.apache.causeway.viewer.graphql.model.marshallers;
 
 import graphql.Scalars;
 
+import graphql.schema.GraphQLEnumType;
+
+import lombok.val;
+
 import javax.annotation.Priority;
 import javax.inject.Inject;
+import javax.inject.Provider;
 
 import org.apache.causeway.applib.annotation.PriorityPrecedence;
 import org.apache.causeway.core.config.CausewayConfiguration;
 
 import 
org.apache.causeway.viewer.graphql.applib.marshallers.ScalarMarshallerAbstract;
 
+import org.apache.causeway.viewer.graphql.model.context.Context;
+
+import org.apache.causeway.viewer.graphql.model.domain.TypeNames;
+
 import org.springframework.stereotype.Component;
 
 
@@ -39,15 +48,13 @@ import org.springframework.stereotype.Component;
 public class ScalarMarshallerObject extends ScalarMarshallerAbstract<Object> {
 
     @Inject
-    public ScalarMarshallerObject(final CausewayConfiguration 
causewayConfiguration) {
+    public ScalarMarshallerObject(
+            final CausewayConfiguration causewayConfiguration) {
         super(Object.class, Scalars.GraphQLString, causewayConfiguration);
     }
 
     @Override
     public Object unmarshal(Object graphValue, Class<?> targetType) {
-        if (targetType.isEnum()) {
-            return Enum.valueOf((Class<Enum>) targetType, 
graphValue.toString());
-        }
         return graphValue;
     }
 }
diff --git 
a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/registry/GraphQLTypeRegistry.java
 
b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/registry/GraphQLTypeRegistry.java
index 8fe4284670..61c1d6047e 100644
--- 
a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/registry/GraphQLTypeRegistry.java
+++ 
b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/registry/GraphQLTypeRegistry.java
@@ -22,23 +22,37 @@ import java.util.Collections;
 import java.util.HashSet;
 import java.util.Optional;
 import java.util.Set;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
 
+import graphql.schema.GraphQLEnumType;
 import graphql.schema.GraphQLInputObjectType;
 import graphql.schema.GraphQLNamedType;
 import graphql.schema.GraphQLObjectType;
 import graphql.schema.GraphQLType;
 
+import org.apache.causeway.viewer.graphql.model.context.Context;
+import org.apache.causeway.viewer.graphql.model.domain.TypeNames;
+
 import org.springframework.stereotype.Component;
 
+import lombok.RequiredArgsConstructor;
 import lombok.extern.log4j.Log4j2;
+import lombok.val;
+
+import javax.inject.Inject;
+import javax.inject.Provider;
+
+import static graphql.schema.GraphQLEnumType.newEnum;
+import static graphql.schema.GraphQLEnumValueDefinition.newEnumValueDefinition;
 
-/**
- * Just a simple wrapper around the set of discovered {@link GraphQLType}s.
- */
 @Component
+@RequiredArgsConstructor(onConstructor_ = {@Inject})
 @Log4j2
 public class GraphQLTypeRegistry {
 
+    private final Provider<Context> contextProvider;
+
     Set<GraphQLType> graphQLTypes = new HashSet<>();
 
     public Set<GraphQLType> getGraphQLTypes() {
@@ -59,8 +73,34 @@ public class GraphQLTypeRegistry {
     }
 
 
+    public GraphQLEnumType addEnumTypeIfNotAlreadyPresent(final Class<?> 
typeToAdd) {
+        val objectSpec = 
contextProvider.get().specificationLoader.loadSpecification(typeToAdd);
+        val typeName = TypeNames.enumTypeNameFor(objectSpec);
+        val enumTypeIfAny = lookup(typeName, GraphQLEnumType.class);
+        if (enumTypeIfAny.isPresent()) {
+            return enumTypeIfAny.get();
+        }
+        val enumType = newEnum()
+                .name(typeName)
+                .values(Stream.of(typeToAdd.getEnumConstants())
+                        .map(enumValue -> newEnumValueDefinition()
+                                .name(enumValue.toString())
+                                .value(enumValue)
+                                .build()).collect(Collectors.toList())
+                )
+                .build();
+        add(enumType);
+        return enumType;
+    }
+
+
     public void addTypeIfNotAlreadyPresent(final GraphQLType typeToAdd) {
 
+        if (typeToAdd instanceof GraphQLEnumType) {
+            addTypeIfNotAlreadyPresent((GraphQLEnumType) typeToAdd);
+            return;
+        }
+
         if (typeToAdd instanceof GraphQLObjectType) {
             addTypeIfNotAlreadyPresent((GraphQLObjectType) typeToAdd);
             return;
@@ -83,6 +123,15 @@ public class GraphQLTypeRegistry {
         log.warn("GraphQLType {} not yet implemented", 
typeToAdd.getClass().getName());
     }
 
+    void addTypeIfNotAlreadyPresent(final GraphQLEnumType typeToAdd){
+        if (isPresent(typeToAdd, GraphQLEnumType.class)){
+            // For now we just log and skip
+            log.debug("GraphQLEnumType for {} already present", 
typeToAdd.getName());
+            return;
+        }
+        add(typeToAdd);
+    }
+
     void addTypeIfNotAlreadyPresent(final GraphQLObjectType typeToAdd){
         if (isPresent(typeToAdd, GraphQLObjectType.class)){
             // For now we just log and skip
diff --git 
a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/types/TypeMapper.java
 
b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/types/TypeMapper.java
index bbe8082d6c..8a3ae353b1 100644
--- 
a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/types/TypeMapper.java
+++ 
b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/types/TypeMapper.java
@@ -28,7 +28,6 @@ import 
org.apache.causeway.core.metamodel.spec.feature.OneToOneFeature;
 import graphql.schema.GraphQLInputType;
 import graphql.schema.GraphQLList;
 import graphql.schema.GraphQLOutputType;
-import graphql.schema.GraphQLScalarType;
 
 /**
  * Internal SPI to map framework's own datatypes to GraphQL's types.
@@ -39,7 +38,9 @@ import graphql.schema.GraphQLScalarType;
  */
 public interface TypeMapper {
 
-    GraphQLScalarType scalarTypeFor(final Class<?> c);
+    GraphQLOutputType outputTypeFor(final Class<?> c);
+
+    GraphQLInputType inputTypeFor(final Class<?> c);
 
     GraphQLOutputType outputTypeFor(final OneToOneFeature oneToOneFeature);
 
diff --git 
a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/types/TypeMapperDefault.java
 
b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/types/TypeMapperDefault.java
index 4d20ba30c5..a318c94b2c 100644
--- 
a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/types/TypeMapperDefault.java
+++ 
b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/types/TypeMapperDefault.java
@@ -19,17 +19,21 @@
 package org.apache.causeway.viewer.graphql.model.types;
 
 import javax.inject.Inject;
+import javax.inject.Provider;
 
 import graphql.Scalars;
+import graphql.schema.GraphQLEnumType;
 import graphql.schema.GraphQLInputType;
 import graphql.schema.GraphQLList;
 import graphql.schema.GraphQLOutputType;
-import graphql.schema.GraphQLScalarType;
+import graphql.schema.GraphQLType;
 import graphql.schema.GraphQLTypeReference;
 
 import static graphql.schema.GraphQLNonNull.nonNull;
 import static graphql.schema.GraphQLTypeReference.typeRef;
 
+import org.apache.causeway.viewer.graphql.model.context.Context;
+
 import 
org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
@@ -44,6 +48,8 @@ import 
org.apache.causeway.viewer.graphql.model.domain.TypeNames;
 import lombok.RequiredArgsConstructor;
 import lombok.val;
 
+import java.util.Optional;
+
 @RequiredArgsConstructor(onConstructor_ = {@Inject})
 public class TypeMapperDefault implements TypeMapper {
 
@@ -52,25 +58,40 @@ public class TypeMapperDefault implements TypeMapper {
 
         @Bean
         @ConditionalOnMissingBean(TypeMapper.class)
-        public TypeMapper defaultTypeMapper(final ScalarMapper scalarMapper) {
-            return new TypeMapperDefault(scalarMapper);
+        public TypeMapper defaultTypeMapper(final ScalarMapper scalarMapper, 
final Provider<Context> contextProvider) {
+            return new TypeMapperDefault(scalarMapper, contextProvider);
         }
     }
 
     private final ScalarMapper scalarMapper;
+    private final Provider<Context> contextProvider;
 
 
     @Override
-    public GraphQLScalarType scalarTypeFor(final Class<?> clazz){
-        GraphQLScalarType scalarType = scalarMapper.scalarTypeFor(clazz);
-        return scalarType;
+    public GraphQLOutputType outputTypeFor(final Class<?> clazz){
+        if (clazz.isEnum()) {
+            return 
contextProvider.get().graphQLTypeRegistry.addEnumTypeIfNotAlreadyPresent(clazz);
+        }
+        return scalarMapper.scalarTypeFor(clazz);
+    }
+
+    @Override
+    public GraphQLInputType inputTypeFor(final Class<?> clazz){
+        if (clazz.isEnum()) {
+            return 
contextProvider.get().graphQLTypeRegistry.addEnumTypeIfNotAlreadyPresent(clazz);
+        }
+        return scalarMapper.scalarTypeFor(clazz);
     }
 
     @Override
     public Object unmarshal(
             final Object gqlValue,
             final ObjectSpecification targetObjectSpec) {
-        return scalarMapper.unmarshal(gqlValue, 
targetObjectSpec.getCorrespondingClass());
+        val correspondingClass = targetObjectSpec.getCorrespondingClass();
+        if (correspondingClass.isEnum()) {
+            return gqlValue;
+        }
+        return scalarMapper.unmarshal(gqlValue, correspondingClass);
     }
 
     @Override
@@ -88,7 +109,7 @@ public class TypeMapperDefault implements TypeMapper {
 
             case VALUE:
 
-                GraphQLScalarType scalarType = 
scalarTypeFor(otoaObjectSpec.getCorrespondingClass());
+                GraphQLOutputType scalarType = 
outputTypeFor(otoaObjectSpec.getCorrespondingClass());
 
                 return oneToOneFeature.isOptional()
                         ? scalarType
@@ -108,7 +129,7 @@ public class TypeMapperDefault implements TypeMapper {
                 return 
typeRef(TypeNames.objectTypeNameFor(objectSpecification));
 
             case VALUE:
-                return 
scalarTypeFor(objectSpecification.getCorrespondingClass());
+                return 
outputTypeFor(objectSpecification.getCorrespondingClass());
 
             case COLLECTION:
                 // should be noop
@@ -133,7 +154,7 @@ public class TypeMapperDefault implements TypeMapper {
             case ENTITY:
                 return 
GraphQLList.list(typeRef(TypeNames.objectTypeNameFor(elementType)));
             case VALUE:
-                return 
GraphQLList.list(scalarTypeFor(elementType.getCorrespondingClass()));
+                return 
GraphQLList.list(outputTypeFor(elementType.getCorrespondingClass()));
         }
         return null;
     }
@@ -156,7 +177,7 @@ public class TypeMapperDefault implements TypeMapper {
                 return typeRef(TypeNames.inputTypeNameFor(elementObjectSpec));
 
             case VALUE:
-                return 
scalarTypeFor(elementObjectSpec.getCorrespondingClass());
+                return inputTypeFor(elementObjectSpec.getCorrespondingClass());
 
             case COLLECTION:
                 throw new 
IllegalArgumentException(String.format("OneToOneFeature '%s' is not expected to 
have a beanSort of COLLECTION", 
oneToOneFeature.getFeatureIdentifier().toString()));
@@ -181,7 +202,7 @@ public class TypeMapperDefault implements TypeMapper {
                 return typeRef(TypeNames.inputTypeNameFor(elementType));
 
             case VALUE:
-                return scalarTypeFor(elementType.getCorrespondingClass());
+                return inputTypeFor(elementType.getCorrespondingClass());
 
             case COLLECTION:
                 throw new IllegalArgumentException(String.format("ObjectSpec 
'%s' is not expected to have a beanSort of COLLECTION", 
elementType.getFullIdentifier()));
diff --git 
a/viewers/graphql/test/src/test/java/org/apache/causeway/viewer/graphql/viewer/test/e2e/query/Admin_IntegTest.java
 
b/viewers/graphql/test/src/test/java/org/apache/causeway/viewer/graphql/viewer/test/e2e/query/Admin_IntegTest.java
index 3d04451c26..776df361a9 100644
--- 
a/viewers/graphql/test/src/test/java/org/apache/causeway/viewer/graphql/viewer/test/e2e/query/Admin_IntegTest.java
+++ 
b/viewers/graphql/test/src/test/java/org/apache/causeway/viewer/graphql/viewer/test/e2e/query/Admin_IntegTest.java
@@ -34,7 +34,6 @@ import lombok.val;
 
 //NOT USING @Transactional since we are running server within same transaction 
otherwise
 @Order(20)
-@DirtiesContext
 @ActiveProfiles("test")
 public class Admin_IntegTest extends Abstract_IntegTest {
 
diff --git 
a/viewers/graphql/test/src/test/java/org/apache/causeway/viewer/graphql/viewer/test/e2e/query/Calculator_IntegTest.java
 
b/viewers/graphql/test/src/test/java/org/apache/causeway/viewer/graphql/viewer/test/e2e/query/Calculator_IntegTest.java
index cb9ace70fa..bdfc29a56d 100644
--- 
a/viewers/graphql/test/src/test/java/org/apache/causeway/viewer/graphql/viewer/test/e2e/query/Calculator_IntegTest.java
+++ 
b/viewers/graphql/test/src/test/java/org/apache/causeway/viewer/graphql/viewer/test/e2e/query/Calculator_IntegTest.java
@@ -32,7 +32,6 @@ import org.springframework.test.context.ActiveProfiles;
 
 //NOT USING @Transactional since we are running server within same transaction 
otherwise
 @Order(30)
-@DirtiesContext
 @ActiveProfiles("test")
 public class Calculator_IntegTest extends Abstract_IntegTest {
 
diff --git 
a/viewers/graphql/test/src/test/java/org/apache/causeway/viewer/graphql/viewer/test/e2e/query/Calculator_IntegTest.next_month._.gql
 
b/viewers/graphql/test/src/test/java/org/apache/causeway/viewer/graphql/viewer/test/e2e/query/Calculator_IntegTest.next_month._.gql
index 70d396c2bf..07a60b63c7 100644
--- 
a/viewers/graphql/test/src/test/java/org/apache/causeway/viewer/graphql/viewer/test/e2e/query/Calculator_IntegTest.next_month._.gql
+++ 
b/viewers/graphql/test/src/test/java/org/apache/causeway/viewer/graphql/viewer/test/e2e/query/Calculator_IntegTest.next_month._.gql
@@ -1,7 +1,7 @@
 {
   university_calc_Calculator {
     nextMonth {
-      invoke(month: "JUNE")
+      invoke(month: JUNE)
     }
   }
 }
diff --git 
a/viewers/graphql/test/src/test/java/org/apache/causeway/viewer/graphql/viewer/test/e2e/query/Department_IntegTest.java
 
b/viewers/graphql/test/src/test/java/org/apache/causeway/viewer/graphql/viewer/test/e2e/query/Department_IntegTest.java
index e956d37201..34945e9656 100644
--- 
a/viewers/graphql/test/src/test/java/org/apache/causeway/viewer/graphql/viewer/test/e2e/query/Department_IntegTest.java
+++ 
b/viewers/graphql/test/src/test/java/org/apache/causeway/viewer/graphql/viewer/test/e2e/query/Department_IntegTest.java
@@ -49,7 +49,6 @@ import lombok.val;
 
 //NOT USING @Transactional since we are running server within same transaction 
otherwise
 @Order(40)
-@DirtiesContext
 @ActiveProfiles("test")
 public class Department_IntegTest extends Abstract_IntegTest {
 
diff --git 
a/viewers/graphql/test/src/test/java/org/apache/causeway/viewer/graphql/viewer/test/e2e/query/DeptHead_IntegTest.java
 
b/viewers/graphql/test/src/test/java/org/apache/causeway/viewer/graphql/viewer/test/e2e/query/DeptHead_IntegTest.java
index 0f0b232175..a1f90571ec 100644
--- 
a/viewers/graphql/test/src/test/java/org/apache/causeway/viewer/graphql/viewer/test/e2e/query/DeptHead_IntegTest.java
+++ 
b/viewers/graphql/test/src/test/java/org/apache/causeway/viewer/graphql/viewer/test/e2e/query/DeptHead_IntegTest.java
@@ -37,7 +37,6 @@ import 
org.apache.causeway.viewer.graphql.viewer.test.domain.dept.DeptHead;
 
 //NOT USING @Transactional since we are running server within same transaction 
otherwise
 @Order(50)
-@DirtiesContext
 @ActiveProfiles("test")
 public class DeptHead_IntegTest extends Abstract_IntegTest {
 
diff --git 
a/viewers/graphql/test/src/test/java/org/apache/causeway/viewer/graphql/viewer/test/e2e/query/Staff_IntegTest.java
 
b/viewers/graphql/test/src/test/java/org/apache/causeway/viewer/graphql/viewer/test/e2e/query/Staff_IntegTest.java
index 0d1d171aec..26e247b706 100644
--- 
a/viewers/graphql/test/src/test/java/org/apache/causeway/viewer/graphql/viewer/test/e2e/query/Staff_IntegTest.java
+++ 
b/viewers/graphql/test/src/test/java/org/apache/causeway/viewer/graphql/viewer/test/e2e/query/Staff_IntegTest.java
@@ -45,7 +45,6 @@ import lombok.val;
 
 //NOT USING @Transactional since we are running server within same transaction 
otherwise
 @Order(60)
-@DirtiesContext
 @ActiveProfiles("test")
 public class Staff_IntegTest extends Abstract_IntegTest {
 
diff --git 
a/viewers/graphql/test/src/test/java/org/apache/causeway/viewer/graphql/viewer/test/e2e/query_and_mutations/DepartmentMutating_IntegTest.java
 
b/viewers/graphql/test/src/test/java/org/apache/causeway/viewer/graphql/viewer/test/e2e/query_and_mutations/DepartmentMutating_IntegTest.java
index 16cabb5dd6..75f2b8a779 100644
--- 
a/viewers/graphql/test/src/test/java/org/apache/causeway/viewer/graphql/viewer/test/e2e/query_and_mutations/DepartmentMutating_IntegTest.java
+++ 
b/viewers/graphql/test/src/test/java/org/apache/causeway/viewer/graphql/viewer/test/e2e/query_and_mutations/DepartmentMutating_IntegTest.java
@@ -41,17 +41,7 @@ import lombok.val;
 
 
 //NOT USING @Transactional since we are running server within same transaction 
otherwise
-@SpringBootTest(
-        classes = {
-                CausewayViewerGraphqlTestModuleIntegTestAbstract.TestApp.class
-        },
-        webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
-        properties = {
-                "causeway.viewer.graphql.api-variant=QUERY_AND_MUTATIONS"
-        }
-)
 @Order(110)
-@DirtiesContext
 @ActiveProfiles("test")
 public class DepartmentMutating_IntegTest extends Abstract_IntegTest {
 
diff --git 
a/viewers/graphql/test/src/test/java/org/apache/causeway/viewer/graphql/viewer/test/e2e/query_and_mutations/DeptHeadMutating_IntegTest.java
 
b/viewers/graphql/test/src/test/java/org/apache/causeway/viewer/graphql/viewer/test/e2e/query_and_mutations/DeptHeadMutating_IntegTest.java
index 841272da3b..8af700f5b5 100644
--- 
a/viewers/graphql/test/src/test/java/org/apache/causeway/viewer/graphql/viewer/test/e2e/query_and_mutations/DeptHeadMutating_IntegTest.java
+++ 
b/viewers/graphql/test/src/test/java/org/apache/causeway/viewer/graphql/viewer/test/e2e/query_and_mutations/DeptHeadMutating_IntegTest.java
@@ -41,17 +41,7 @@ import lombok.val;
 
 
 //NOT USING @Transactional since we are running server within same transaction 
otherwise
-@SpringBootTest(
-        classes = {
-                CausewayViewerGraphqlTestModuleIntegTestAbstract.TestApp.class
-        },
-        webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
-        properties = {
-                "causeway.viewer.graphql.api-variant=QUERY_AND_MUTATIONS"
-        }
-)
 @Order(120)
-@DirtiesContext
 @ActiveProfiles("test")
 public class DeptHeadMutating_IntegTest extends Abstract_IntegTest {
 
diff --git 
a/viewers/graphql/test/src/test/java/org/apache/causeway/viewer/graphql/viewer/test/e2e/query_and_mutations/StaffMutating_IntegTest.java
 
b/viewers/graphql/test/src/test/java/org/apache/causeway/viewer/graphql/viewer/test/e2e/query_and_mutations/StaffMutating_IntegTest.java
index 4271688feb..97b1485079 100644
--- 
a/viewers/graphql/test/src/test/java/org/apache/causeway/viewer/graphql/viewer/test/e2e/query_and_mutations/StaffMutating_IntegTest.java
+++ 
b/viewers/graphql/test/src/test/java/org/apache/causeway/viewer/graphql/viewer/test/e2e/query_and_mutations/StaffMutating_IntegTest.java
@@ -38,17 +38,7 @@ import lombok.val;
 
 
 // NOT USING @Transactional since we are running server within same 
transaction otherwise
-@SpringBootTest(
-        classes = {
-                CausewayViewerGraphqlTestModuleIntegTestAbstract.TestApp.class
-        },
-        webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
-        properties = {
-                "causeway.viewer.graphql.api-variant=QUERY_AND_MUTATIONS"
-        }
-)
 @Order(130)
-@DirtiesContext
 @ActiveProfiles("test")
 public class StaffMutating_IntegTest extends Abstract_IntegTest {
 
diff --git 
a/viewers/graphql/test/src/test/java/org/apache/causeway/viewer/graphql/viewer/test/e2e/query_and_mutations/_Mutating_IntegTest.java
 
b/viewers/graphql/test/src/test/java/org/apache/causeway/viewer/graphql/viewer/test/e2e/query_and_mutations/_Mutating_IntegTest.java
deleted file mode 100644
index 1ba74c632d..0000000000
--- 
a/viewers/graphql/test/src/test/java/org/apache/causeway/viewer/graphql/viewer/test/e2e/query_and_mutations/_Mutating_IntegTest.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *        http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- */
-package org.apache.causeway.viewer.graphql.viewer.test.e2e.query_and_mutations;
-
-import org.junit.jupiter.api.Order;
-import org.junit.jupiter.api.Test;
-import org.springframework.boot.test.context.SpringBootTest;
-import org.springframework.test.annotation.DirtiesContext;
-import org.springframework.test.context.ActiveProfiles;
-
-import 
org.apache.causeway.viewer.graphql.viewer.test.CausewayViewerGraphqlTestModuleIntegTestAbstract;
-import org.apache.causeway.viewer.graphql.viewer.test.e2e.Abstract_IntegTest;
-
-
-//NOT USING @Transactional since we are running server within same transaction 
otherwise
-@SpringBootTest(
-        classes = {
-                CausewayViewerGraphqlTestModuleIntegTestAbstract.TestApp.class
-        },
-        webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
-        properties = {
-                "causeway.viewer.graphql.api-variant=QUERY_AND_MUTATIONS"
-        }
-)
-@Order(100)
-@ActiveProfiles("test")
-@DirtiesContext
-public class _Mutating_IntegTest extends Abstract_IntegTest {
-
-    @Test
-    void dummy() throws Exception {
-    }
-
-}
diff --git 
a/viewers/graphql/test/src/test/java/org/apache/causeway/viewer/graphql/viewer/test/e2e/scenario/Calculator_IntegTest.java
 
b/viewers/graphql/test/src/test/java/org/apache/causeway/viewer/graphql/viewer/test/e2e/scenario/Calculator_IntegTest.java
index 79a079c6ab..194c9a154f 100644
--- 
a/viewers/graphql/test/src/test/java/org/apache/causeway/viewer/graphql/viewer/test/e2e/scenario/Calculator_IntegTest.java
+++ 
b/viewers/graphql/test/src/test/java/org/apache/causeway/viewer/graphql/viewer/test/e2e/scenario/Calculator_IntegTest.java
@@ -31,7 +31,6 @@ import 
org.apache.causeway.viewer.graphql.viewer.test.e2e.Abstract_IntegTest;
 
 //NOT USING @Transactional since we are running server within same transaction 
otherwise
 @Order(30)
-@DirtiesContext
 @ActiveProfiles("test")
 public class Calculator_IntegTest extends Abstract_IntegTest {
 
diff --git 
a/viewers/graphql/test/src/test/java/org/apache/causeway/viewer/graphql/viewer/test/e2e/scenario/Department_IntegTest.java
 
b/viewers/graphql/test/src/test/java/org/apache/causeway/viewer/graphql/viewer/test/e2e/scenario/Department_IntegTest.java
index 9e519e264e..0a71daee6e 100644
--- 
a/viewers/graphql/test/src/test/java/org/apache/causeway/viewer/graphql/viewer/test/e2e/scenario/Department_IntegTest.java
+++ 
b/viewers/graphql/test/src/test/java/org/apache/causeway/viewer/graphql/viewer/test/e2e/scenario/Department_IntegTest.java
@@ -31,7 +31,6 @@ import 
org.apache.causeway.viewer.graphql.viewer.test.e2e.Abstract_IntegTest;
 
 //NOT USING @Transactional since we are running server within same transaction 
otherwise
 @Order(40)
-@DirtiesContext
 @ActiveProfiles("test")
 public class Department_IntegTest extends Abstract_IntegTest {
 
diff --git 
a/viewers/graphql/test/src/test/java/org/apache/causeway/viewer/graphql/viewer/test/schema/query/GqlSchemaQuery_print_IntegTest.java
 
b/viewers/graphql/test/src/test/java/org/apache/causeway/viewer/graphql/viewer/test/schema/GqlSchemaQuery_print_IntegTest.java
similarity index 94%
rename from 
viewers/graphql/test/src/test/java/org/apache/causeway/viewer/graphql/viewer/test/schema/query/GqlSchemaQuery_print_IntegTest.java
rename to 
viewers/graphql/test/src/test/java/org/apache/causeway/viewer/graphql/viewer/test/schema/GqlSchemaQuery_print_IntegTest.java
index a3d69011ef..f911dbfd5b 100644
--- 
a/viewers/graphql/test/src/test/java/org/apache/causeway/viewer/graphql/viewer/test/schema/query/GqlSchemaQuery_print_IntegTest.java
+++ 
b/viewers/graphql/test/src/test/java/org/apache/causeway/viewer/graphql/viewer/test/schema/GqlSchemaQuery_print_IntegTest.java
@@ -16,7 +16,7 @@
  *  specific language governing permissions and limitations
  *  under the License.
  */
-package org.apache.causeway.viewer.graphql.viewer.test.schema.query;
+package org.apache.causeway.viewer.graphql.viewer.test.schema;
 
 import org.junit.jupiter.api.Order;
 
diff --git 
a/viewers/graphql/test/src/test/java/org/apache/causeway/viewer/graphql/viewer/test/schema/query_and_mutations/GqlSchemaQueryAndMutations_print_IntegTest.java
 
b/viewers/graphql/test/src/test/java/org/apache/causeway/viewer/graphql/viewer/test/schema/query_and_mutations/GqlSchemaQueryAndMutations_print_IntegTest.java
deleted file mode 100644
index 43c979e129..0000000000
--- 
a/viewers/graphql/test/src/test/java/org/apache/causeway/viewer/graphql/viewer/test/schema/query_and_mutations/GqlSchemaQueryAndMutations_print_IntegTest.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *        http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- */
-package 
org.apache.causeway.viewer.graphql.viewer.test.schema.query_and_mutations;
-
-import org.junit.jupiter.api.Order;
-
-import org.springframework.boot.test.context.SpringBootTest;
-import org.springframework.test.annotation.DirtiesContext;
-import org.springframework.transaction.annotation.Transactional;
-
-import 
org.apache.causeway.viewer.graphql.viewer.test.CausewayViewerGraphqlTestModuleIntegTestAbstract;
-import 
org.apache.causeway.viewer.graphql.viewer.test.schema.AbstractGqlSchema_print_IntegTest;
-
-@SpringBootTest(
-        classes = {
-                CausewayViewerGraphqlTestModuleIntegTestAbstract.TestApp.class
-        },
-        webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
-        properties = {
-                "causeway.viewer.graphql.api-variant=QUERY_AND_MUTATIONS"
-        }
-)
-@Order(100)
-@Transactional
-@DirtiesContext
-public class GqlSchemaQueryAndMutations_print_IntegTest extends 
AbstractGqlSchema_print_IntegTest {
-
-}
diff --git a/viewers/graphql/test/src/test/resources/schema.gql 
b/viewers/graphql/test/src/test/resources/schema.gql
index 9e0889217c..e01f63e586 100644
--- a/viewers/graphql/test/src/test/resources/schema.gql
+++ b/viewers/graphql/test/src/test/resources/schema.gql
@@ -22,6 +22,50 @@ directive @specifiedBy(
     url: String!
   ) on SCALAR
 
+type Mutation {
+  causeway_applib_PropertyNode__mixedIn(_gqlv_target: 
causeway_applib_PropertyNode__gqlv_input, mixedIn: Boolean!): 
causeway_applib_PropertyNode
+  causeway_applib_node_ActionNode__mixedIn(_gqlv_target: 
causeway_applib_node_ActionNode__gqlv_input, mixedIn: Boolean!): 
causeway_applib_node_ActionNode
+  causeway_applib_node_CollectionNode__mixedIn(_gqlv_target: 
causeway_applib_node_CollectionNode__gqlv_input, mixedIn: Boolean!): 
causeway_applib_node_CollectionNode
+  causeway_applib_node_FacetNode__shadowed(_gqlv_target: 
causeway_applib_node_FacetNode__gqlv_input, shadowed: Boolean!): 
causeway_applib_node_FacetNode
+  causeway_conf_ConfigurationProperty__key(_gqlv_target: 
causeway_conf_ConfigurationProperty__gqlv_input, key: String!): 
causeway_conf_ConfigurationProperty
+  causeway_conf_ConfigurationProperty__value(_gqlv_target: 
causeway_conf_ConfigurationProperty__gqlv_input, value: String!): 
causeway_conf_ConfigurationProperty
+  causeway_schema_metamodel_v2_DomainClassDto__actions(_gqlv_target: 
causeway_schema_metamodel_v2_DomainClassDto__gqlv_input, actions: String!): 
causeway_schema_metamodel_v2_DomainClassDto
+  causeway_schema_metamodel_v2_DomainClassDto__annotations(_gqlv_target: 
causeway_schema_metamodel_v2_DomainClassDto__gqlv_input, annotations: String!): 
causeway_schema_metamodel_v2_DomainClassDto
+  causeway_schema_metamodel_v2_DomainClassDto__collections(_gqlv_target: 
causeway_schema_metamodel_v2_DomainClassDto__gqlv_input, collections: String!): 
causeway_schema_metamodel_v2_DomainClassDto
+  causeway_schema_metamodel_v2_DomainClassDto__facets(_gqlv_target: 
causeway_schema_metamodel_v2_DomainClassDto__gqlv_input, facets: String!): 
causeway_schema_metamodel_v2_DomainClassDto
+  causeway_schema_metamodel_v2_DomainClassDto__id(_gqlv_target: 
causeway_schema_metamodel_v2_DomainClassDto__gqlv_input, id: String!): 
causeway_schema_metamodel_v2_DomainClassDto
+  causeway_schema_metamodel_v2_DomainClassDto__majorVersion(_gqlv_target: 
causeway_schema_metamodel_v2_DomainClassDto__gqlv_input, majorVersion: String): 
causeway_schema_metamodel_v2_DomainClassDto
+  causeway_schema_metamodel_v2_DomainClassDto__minorVersion(_gqlv_target: 
causeway_schema_metamodel_v2_DomainClassDto__gqlv_input, minorVersion: String): 
causeway_schema_metamodel_v2_DomainClassDto
+  causeway_schema_metamodel_v2_DomainClassDto__properties(_gqlv_target: 
causeway_schema_metamodel_v2_DomainClassDto__gqlv_input, properties: String!): 
causeway_schema_metamodel_v2_DomainClassDto
+  causeway_schema_metamodel_v2_DomainClassDto__service(_gqlv_target: 
causeway_schema_metamodel_v2_DomainClassDto__gqlv_input, service: Boolean!): 
causeway_schema_metamodel_v2_DomainClassDto
+  
causeway_testing_fixtures_FixtureResult__fixtureScriptClassName(_gqlv_target: 
causeway_testing_fixtures_FixtureResult__gqlv_input, fixtureScriptClassName: 
String): causeway_testing_fixtures_FixtureResult
+  causeway_testing_fixtures_FixtureResult__key(_gqlv_target: 
causeway_testing_fixtures_FixtureResult__gqlv_input, key: String!): 
causeway_testing_fixtures_FixtureResult
+  causeway_testing_fixtures_FixtureResult__object(_gqlv_target: 
causeway_testing_fixtures_FixtureResult__gqlv_input, object: String!): 
causeway_testing_fixtures_FixtureResult
+  
org_apache_causeway_core_metamodel_inspect_model_MemberNode__mixedIn(_gqlv_target:
 org_apache_causeway_core_metamodel_inspect_model_MemberNode__gqlv_input, 
mixedIn: Boolean!): org_apache_causeway_core_metamodel_inspect_model_MemberNode
+  
org_apache_causeway_testing_fixtures_applib_fixturescripts_FixtureScript__friendlyName(_gqlv_target:
 
org_apache_causeway_testing_fixtures_applib_fixturescripts_FixtureScript__gqlv_input,
 friendlyName: String!): 
org_apache_causeway_testing_fixtures_applib_fixturescripts_FixtureScript
+  university_admin_AdminMenu__actionWithDisabledParam(firstParam: String!, 
secondParam: String!, thirdParameter: String!): String
+  university_admin_AdminMenu__actionWithHiddenParam(firstParam: String!, 
secondParam: String!): String
+  university_admin_AdminMenu__adminAction: String
+  university_admin_AdminMenu__otherAdminAction: String
+  university_dept_Department__addStaffMember(_gqlv_target: 
university_dept_Department__gqlv_input, staffMember: 
university_dept_StaffMember__gqlv_input!): university_dept_Department
+  university_dept_Department__addStaffMembers(_gqlv_target: 
university_dept_Department__gqlv_input, staffMembers: 
[university_dept_StaffMember__gqlv_input]): university_dept_Department
+  university_dept_Department__changeDeptHead(_gqlv_target: 
university_dept_Department__gqlv_input, newDeptHead: 
university_dept_DeptHead__gqlv_input!): university_dept_Department
+  university_dept_Department__changeName(_gqlv_target: 
university_dept_Department__gqlv_input, newName: String!): 
university_dept_Department
+  university_dept_Department__deptHead(_gqlv_target: 
university_dept_Department__gqlv_input, deptHead: 
university_dept_DeptHead__gqlv_input): university_dept_Department
+  university_dept_Department__name(_gqlv_target: 
university_dept_Department__gqlv_input, name: String!): 
university_dept_Department
+  university_dept_Department__removeStaffMember(_gqlv_target: 
university_dept_Department__gqlv_input, staffMember: 
university_dept_StaffMember__gqlv_input!): university_dept_Department
+  university_dept_Departments__createDepartment(deptHead: 
university_dept_DeptHead__gqlv_input, name: String!): university_dept_Department
+  university_dept_DeptHead__changeDepartment(_gqlv_target: 
university_dept_DeptHead__gqlv_input, department: 
university_dept_Department__gqlv_input!): university_dept_DeptHead
+  university_dept_DeptHead__changeName(_gqlv_target: 
university_dept_DeptHead__gqlv_input, newName: String!): 
university_dept_DeptHead
+  university_dept_DeptHead__department(_gqlv_target: 
university_dept_DeptHead__gqlv_input, department: 
university_dept_Department__gqlv_input): university_dept_DeptHead
+  university_dept_DeptHead__name(_gqlv_target: 
university_dept_DeptHead__gqlv_input, name: String): university_dept_DeptHead
+  university_dept_StaffMember__department(_gqlv_target: 
university_dept_StaffMember__gqlv_input, department: 
university_dept_Department__gqlv_input): university_dept_StaffMember
+  university_dept_StaffMember__grade(_gqlv_target: 
university_dept_StaffMember__gqlv_input, grade: 
org_apache_causeway_viewer_graphql_viewer_test_domain_dept_Grade__gqlv_enum!): 
university_dept_StaffMember
+  university_dept_StaffMember__name(_gqlv_target: 
university_dept_StaffMember__gqlv_input, name: String!): 
university_dept_StaffMember
+  university_dept_StaffMember__photo(_gqlv_target: 
university_dept_StaffMember__gqlv_input, photo: String): 
university_dept_StaffMember
+  university_dept_Staff__createStaffMember(department: 
university_dept_Department__gqlv_input!, name: String!): 
university_dept_StaffMember
+}
+
 type Query {
   Scenario(name: String): Scenario
   causeway_applib_DomainObjectList(object: 
causeway_applib_DomainObjectList__gqlv_input): causeway_applib_DomainObjectList
@@ -382,12 +426,12 @@ type 
causeway_applib_UserMemento__authenticationCode__gqlv_property {
 }
 
 type causeway_applib_UserMemento__authenticationSource__gqlv_property {
-  choices(authenticationSource: String): [String]
+  choices(authenticationSource: 
org_apache_causeway_applib_services_user_UserMemento_AuthenticationSource__gqlv_enum):
 
[org_apache_causeway_applib_services_user_UserMemento_AuthenticationSource__gqlv_enum]
   disabled: String
-  get: String!
+  get: 
org_apache_causeway_applib_services_user_UserMemento_AuthenticationSource__gqlv_enum!
   hidden: Boolean
-  set(authenticationSource: String!): causeway_applib_UserMemento
-  validate(authenticationSource: String): String
+  set(authenticationSource: 
org_apache_causeway_applib_services_user_UserMemento_AuthenticationSource__gqlv_enum!):
 causeway_applib_UserMemento
+  validate(authenticationSource: 
org_apache_causeway_applib_services_user_UserMemento_AuthenticationSource__gqlv_enum):
 String
 }
 
 type causeway_applib_UserMemento__avatarUrl__gqlv_property {
@@ -828,12 +872,12 @@ type causeway_feat_ApplicationTypeAction {
 }
 
 type causeway_feat_ApplicationTypeAction__actionSemantics__gqlv_property {
-  choices(actionSemantics: String): [String]
+  choices(actionSemantics: causeway_applib_annotation_SemanticsOf__gqlv_enum): 
[causeway_applib_annotation_SemanticsOf__gqlv_enum]
   disabled: String
-  get: String!
+  get: causeway_applib_annotation_SemanticsOf__gqlv_enum!
   hidden: Boolean
-  set(actionSemantics: String!): causeway_feat_ApplicationTypeAction
-  validate(actionSemantics: String): String
+  set(actionSemantics: causeway_applib_annotation_SemanticsOf__gqlv_enum!): 
causeway_feat_ApplicationTypeAction
+  validate(actionSemantics: 
causeway_applib_annotation_SemanticsOf__gqlv_enum): String
 }
 
 type causeway_feat_ApplicationTypeAction__gqlv_meta {
@@ -1901,9 +1945,9 @@ type 
university_calc_Calculator__concat__suffix__gqlv_action_parameter {
 type university_calc_Calculator__nextMonth__gqlv_action {
   disabled: String
   hidden: Boolean
-  invoke(month: String!): String
+  invoke(month: 
org_apache_causeway_viewer_graphql_viewer_test_domain_calc_Month__gqlv_enum!): 
org_apache_causeway_viewer_graphql_viewer_test_domain_calc_Month__gqlv_enum
   params: university_calc_Calculator__nextMonth__gqlv_action_params
-  validate(month: String): String
+  validate(month: 
org_apache_causeway_viewer_graphql_viewer_test_domain_calc_Month__gqlv_enum): 
String
 }
 
 type university_calc_Calculator__nextMonth__gqlv_action_params {
@@ -1911,8 +1955,8 @@ type 
university_calc_Calculator__nextMonth__gqlv_action_params {
 }
 
 type university_calc_Calculator__nextMonth__month__gqlv_action_parameter {
-  choices: [String]
-  disabled(month: String): String
+  choices: 
[org_apache_causeway_viewer_graphql_viewer_test_domain_calc_Month__gqlv_enum]
+  disabled(month: 
org_apache_causeway_viewer_graphql_viewer_test_domain_calc_Month__gqlv_enum): 
String
   hidden: Boolean
   validity: String
 }
@@ -2355,12 +2399,12 @@ type university_dept_StaffMember__gqlv_meta {
 }
 
 type university_dept_StaffMember__grade__gqlv_property {
-  choices(grade: String): [String]
+  choices(grade: 
org_apache_causeway_viewer_graphql_viewer_test_domain_dept_Grade__gqlv_enum): 
[org_apache_causeway_viewer_graphql_viewer_test_domain_dept_Grade__gqlv_enum]
   disabled: String
-  get: String!
+  get: 
org_apache_causeway_viewer_graphql_viewer_test_domain_dept_Grade__gqlv_enum!
   hidden: Boolean
-  set(grade: String!): university_dept_StaffMember
-  validate(grade: String): String
+  set(grade: 
org_apache_causeway_viewer_graphql_viewer_test_domain_dept_Grade__gqlv_enum!): 
university_dept_StaffMember
+  validate(grade: 
org_apache_causeway_viewer_graphql_viewer_test_domain_dept_Grade__gqlv_enum): 
String
 }
 
 type university_dept_StaffMember__name__gqlv_property {
@@ -2433,6 +2477,44 @@ type 
university_dept_Staff__findStaffMemberByName__name__gqlv_action_parameter {
   validity: String
 }
 
+enum causeway_applib_annotation_SemanticsOf__gqlv_enum {
+  IDEMPOTENT
+  IDEMPOTENT_ARE_YOU_SURE
+  NON_IDEMPOTENT
+  NON_IDEMPOTENT_ARE_YOU_SURE
+  NOT_SPECIFIED
+  SAFE
+  SAFE_AND_REQUEST_CACHEABLE
+}
+
+enum 
org_apache_causeway_applib_services_user_UserMemento_AuthenticationSource__gqlv_enum
 {
+  DEFAULT
+  EXTERNAL
+}
+
+enum 
org_apache_causeway_viewer_graphql_viewer_test_domain_calc_Month__gqlv_enum {
+  APRIL
+  AUGUST
+  DECEMBER
+  FEBRUARY
+  JANUARY
+  JULY
+  JUNE
+  MARCH
+  MAY
+  NOVEMBER
+  OCTOBER
+  SEPTEMBER
+}
+
+enum 
org_apache_causeway_viewer_graphql_viewer_test_domain_dept_Grade__gqlv_enum {
+  LECTURER
+  PROFESSOR
+  READER
+  RESEARCH_ASSISTANT
+  SENIOR_LECTURER
+}
+
 input causeway_applib_DomainObjectList__gqlv_input {
   id: ID
   ref: String
diff --git 
a/viewers/graphql/viewer/src/main/java/org/apache/causeway/viewer/graphql/viewer/integration/GraphQlSourceForCauseway.java
 
b/viewers/graphql/viewer/src/main/java/org/apache/causeway/viewer/graphql/viewer/integration/GraphQlSourceForCauseway.java
index b1475ddb38..59f330d00a 100644
--- 
a/viewers/graphql/viewer/src/main/java/org/apache/causeway/viewer/graphql/viewer/integration/GraphQlSourceForCauseway.java
+++ 
b/viewers/graphql/viewer/src/main/java/org/apache/causeway/viewer/graphql/viewer/integration/GraphQlSourceForCauseway.java
@@ -21,6 +21,10 @@ package 
org.apache.causeway.viewer.graphql.viewer.integration;
 import javax.annotation.PostConstruct;
 import javax.inject.Inject;
 
+import org.apache.causeway.viewer.graphql.model.domain.GqlvDomainObject;
+
+import org.apache.causeway.viewer.graphql.model.domain.TypeNames;
+
 import org.springframework.graphql.execution.GraphQlSource;
 import org.springframework.stereotype.Service;
 
@@ -37,10 +41,19 @@ import graphql.GraphQL;
 import graphql.execution.DataFetcherExceptionHandler;
 import graphql.execution.DataFetcherExceptionHandlerParameters;
 import graphql.execution.DataFetcherExceptionHandlerResult;
+import graphql.schema.GraphQLEnumType;
+import graphql.schema.GraphQLEnumValueDefinition;
+import graphql.schema.GraphQLNamedType;
 import graphql.schema.GraphQLSchema;
 import lombok.RequiredArgsConstructor;
 import lombok.val;
 
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import static graphql.schema.GraphQLEnumType.newEnum;
+import static graphql.schema.GraphQLEnumValueDefinition.*;
+
 @Service()
 @RequiredArgsConstructor(onConstructor_ = {@Inject})
 public class GraphQlSourceForCauseway implements GraphQlSource {

Reply via email to