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
The following commit(s) were added to refs/heads/CAUSEWAY-3676 by this push:
new 1f5dfa52e2 CAUSEWAY-3676: adds example of specifying a reference to an
entity as an input type
1f5dfa52e2 is described below
commit 1f5dfa52e2a5279892c6f80ef964be2391c64fec
Author: danhaywood <[email protected]>
AuthorDate: Wed Jan 24 23:19:01 2024 +0000
CAUSEWAY-3676: adds example of specifying a reference to an entity as an
input type
---
.../viewer/graphql/model/domain/GqlvAction.java | 2 +-
.../graphql/model/domain/GqlvActionInvoke.java | 44 ++++++++++++++++++++--
...ayViewerGraphqlTestModuleIntegTestAbstract.java | 33 +++++++++++++---
...gTest.create_staff_member_with_department._.gql | 18 +++++++++
...eate_staff_member_with_department.approved.json | 20 ++++++++++
.../graphql/viewer/test/e2e/Domain_IntegTest.java | 21 +++++++++++
6 files changed, 128 insertions(+), 10 deletions(-)
diff --git
a/incubator/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/GqlvAction.java
b/incubator/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/GqlvAction.java
index f51077c69d..2125886224 100644
---
a/incubator/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/GqlvAction.java
+++
b/incubator/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/GqlvAction.java
@@ -60,7 +60,7 @@ public class GqlvAction
this.hidden = new GqlvMemberHidden(this, codeRegistryBuilder);
this.disabled = new GqlvMemberDisabled(this, codeRegistryBuilder);
this.validate = new GqlvActionValidate(this, codeRegistryBuilder);
- this.invoke = new GqlvActionInvoke(this, codeRegistryBuilder);
+ this.invoke = new GqlvActionInvoke(this, codeRegistryBuilder,
bookmarkService);
this.gqlObjectType = gqlObjectTypeBuilder.build();
diff --git
a/incubator/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/GqlvActionInvoke.java
b/incubator/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/GqlvActionInvoke.java
index 925e825fae..79ac4ef813 100644
---
a/incubator/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/GqlvActionInvoke.java
+++
b/incubator/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/GqlvActionInvoke.java
@@ -19,9 +19,11 @@
package org.apache.causeway.viewer.graphql.model.domain;
import java.util.Map;
+import java.util.Optional;
import java.util.stream.Collectors;
-import org.apache.causeway.core.metamodel.consent.Consent;
+import org.apache.causeway.applib.services.bookmark.Bookmark;
+import org.apache.causeway.applib.services.bookmark.BookmarkService;
import org.apache.causeway.core.metamodel.spec.feature.OneToOneActionParameter;
import org.springframework.lang.Nullable;
@@ -54,14 +56,16 @@ public class GqlvActionInvoke {
private final GqlvActionInvokeHolder holder;
private final GraphQLCodeRegistry.Builder codeRegistryBuilder;
private final GraphQLFieldDefinition field;
+ private final BookmarkService bookmarkService;
public GqlvActionInvoke(
final GqlvActionInvokeHolder holder,
- final GraphQLCodeRegistry.Builder codeRegistryBuilder
- ) {
+ final GraphQLCodeRegistry.Builder codeRegistryBuilder,
+ final BookmarkService bookmarkService) {
this.holder = holder;
this.codeRegistryBuilder = codeRegistryBuilder;
this.field = fieldDefinition(holder);
+ this.bookmarkService = bookmarkService;
}
private static GraphQLFieldDefinition fieldDefinition(final
GqlvActionInvokeHolder holder) {
@@ -178,8 +182,40 @@ public class GqlvActionInvoke {
Can<ObjectActionParameter> parameters = objectAction.getParameters();
Can<ManagedObject> argumentManagedObjects = parameters
.map(oap -> {
+ final ObjectSpecification elementType =
oap.getElementType();
Object argumentValue = argumentPojos.get(oap.getId());
- return ManagedObject.adaptParameter(oap, argumentValue);
+ switch (elementType.getBeanSort()) {
+
+ case VALUE:
+ return ManagedObject.adaptParameter(oap,
argumentValue);
+
+ case ENTITY:
+ case VIEW_MODEL:
+ //noinspection unchecked
+ if (argumentValue == null) {
+ return ManagedObject.empty(elementType);
+ }
+ String idValue = ((Map<String, String>)
argumentValue).get("id");
+ Class<?> paramClass =
elementType.getCorrespondingClass();
+ Optional<Bookmark> bookmarkIfAny =
bookmarkService.bookmarkFor(paramClass, idValue);
+ return bookmarkIfAny
+ .map(bookmarkService::lookup)
+ .filter(Optional::isPresent)
+ .map(Optional::get)
+ .map(pojo ->
ManagedObject.adaptParameter(oap, pojo))
+ .orElse(ManagedObject.empty(elementType));
+
+ case ABSTRACT:
+ case COLLECTION:
+ case MANAGED_BEAN_CONTRIBUTING:
+ case VETOED:
+ case MANAGED_BEAN_NOT_CONTRIBUTING:
+ case MIXIN:
+ case UNKNOWN:
+ default:
+ throw new IllegalArgumentException(String.format(
+ "Cannot handle an input type for %s;
beanSort is %s", elementType.getFullIdentifier(), elementType.getBeanSort()));
+ }
});
val consent = objectAction.isArgumentSetValid(actionInteractionHead,
argumentManagedObjects, InteractionInitiatedBy.USER);
diff --git
a/incubator/viewers/graphql/test/src/test/java/org/apache/causeway/viewer/graphql/viewer/test/CausewayViewerGraphqlTestModuleIntegTestAbstract.java
b/incubator/viewers/graphql/test/src/test/java/org/apache/causeway/viewer/graphql/viewer/test/CausewayViewerGraphqlTestModuleIntegTestAbstract.java
index f07abad316..1496364764 100644
---
a/incubator/viewers/graphql/test/src/test/java/org/apache/causeway/viewer/graphql/viewer/test/CausewayViewerGraphqlTestModuleIntegTestAbstract.java
+++
b/incubator/viewers/graphql/test/src/test/java/org/apache/causeway/viewer/graphql/viewer/test/CausewayViewerGraphqlTestModuleIntegTestAbstract.java
@@ -28,6 +28,8 @@ import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
+import java.util.Collections;
+import java.util.Map;
import javax.inject.Inject;
@@ -36,7 +38,6 @@ import
org.apache.causeway.commons.internal.resources._Resources;
import org.apache.causeway.core.config.environment.CausewaySystemEnvironment;
import org.apache.causeway.core.metamodel.specloader.SpecificationLoader;
-import
org.apache.causeway.testing.fixtures.applib.CausewayIntegrationTestAbstractWithFixtures;
import
org.apache.causeway.viewer.graphql.viewer.integration.ExecutionGraphQlServiceForCauseway;
import
org.apache.causeway.viewer.graphql.viewer.integration.GraphQlSourceForCauseway;
@@ -156,7 +157,11 @@ public abstract class
CausewayViewerGraphqlTestModuleIntegTestAbstract {
* @throws Exception if an error occurs during the submission
*/
protected String submit() throws Exception{
- val httpRequest = buildRequest(testInfo, "._.gql");
+ return submit(Collections.emptyMap());
+ }
+
+ protected String submit(Map<String,String> replacements) throws Exception{
+ val httpRequest = buildRequest(testInfo, "._.gql", replacements);
return submitRequest(httpRequest);
}
@@ -167,15 +172,17 @@ public abstract class
CausewayViewerGraphqlTestModuleIntegTestAbstract {
protected HttpRequest buildRequest(
final TestInfo testInfo,
- final String resourceSuffix) throws IOException {
+ final String resourceSuffix,
+ final Map<String, String> replacements) throws IOException {
val testMethodName =
testInfo.getTestMethod().map(Method::getName).get();
val resourceName = getClass().getSimpleName() + "." + testMethodName +
resourceSuffix;
- val resourceContents = readResource(resourceName);
+ String resourceContents = readResource(resourceName);
+ String resourceContent = replace(resourceContents, replacements);
val uri = URI.create(String.format("http://0.0.0.0:%d/graphql", port));
- val gqlBody = new GqlBody(resourceContents);
+ val gqlBody = new GqlBody(resourceContent);
val gqlBodyStr = objectMapper.writeValueAsString(gqlBody);
val bodyPublisher = HttpRequest.BodyPublishers.ofString(gqlBodyStr);
@@ -186,6 +193,22 @@ public abstract class
CausewayViewerGraphqlTestModuleIntegTestAbstract {
build();
}
+ private static String replace(String str, Map<String, String>
replacements) {
+ val builder = new StringBuilder(str);
+ replacements.forEach((key, value) -> {
+ int index;
+ int numMatches = 0;
+ while ((index = builder.indexOf(key)) != -1) {
+ builder.replace(index, index + key.length(), value);
+ numMatches++;
+ }
+ if (numMatches == 0) {
+ throw new IllegalArgumentException("Could not find '" + key +
"' to replace");
+ }
+ });
+ return builder.toString();
+ }
+
private String submitRequest(final HttpRequest request) throws
IOException, InterruptedException {
val responseBodyHandler = HttpResponse.BodyHandlers.ofString();
val httpClient = HttpClient.newBuilder().build();
diff --git
a/incubator/viewers/graphql/test/src/test/java/org/apache/causeway/viewer/graphql/viewer/test/e2e/Domain_IntegTest.create_staff_member_with_department._.gql
b/incubator/viewers/graphql/test/src/test/java/org/apache/causeway/viewer/graphql/viewer/test/e2e/Domain_IntegTest.create_staff_member_with_department._.gql
new file mode 100644
index 0000000000..fc14f7ac4a
--- /dev/null
+++
b/incubator/viewers/graphql/test/src/test/java/org/apache/causeway/viewer/graphql/viewer/test/e2e/Domain_IntegTest.create_staff_member_with_department._.gql
@@ -0,0 +1,18 @@
+{
+ university_dept_Staff {
+ createStaffMember {
+ invokeNonIdempotent(name: "Dr. Georgina McGovern", department: { id:
"$departmentId"}) {
+ name {
+ get
+ }
+ department {
+ get {
+ name {
+ get
+ }
+ }
+ }
+ }
+ }
+ }
+}
diff --git
a/incubator/viewers/graphql/test/src/test/java/org/apache/causeway/viewer/graphql/viewer/test/e2e/Domain_IntegTest.create_staff_member_with_department.approved.json
b/incubator/viewers/graphql/test/src/test/java/org/apache/causeway/viewer/graphql/viewer/test/e2e/Domain_IntegTest.create_staff_member_with_department.approved.json
new file mode 100644
index 0000000000..1b1ab53dad
--- /dev/null
+++
b/incubator/viewers/graphql/test/src/test/java/org/apache/causeway/viewer/graphql/viewer/test/e2e/Domain_IntegTest.create_staff_member_with_department.approved.json
@@ -0,0 +1,20 @@
+{
+ "data" : {
+ "university_dept_Staff" : {
+ "createStaffMember" : {
+ "invokeNonIdempotent" : {
+ "name" : {
+ "get" : "Dr. Georgina McGovern"
+ },
+ "department" : {
+ "get" : {
+ "name" : {
+ "get" : "Classics"
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git
a/incubator/viewers/graphql/test/src/test/java/org/apache/causeway/viewer/graphql/viewer/test/e2e/Domain_IntegTest.java
b/incubator/viewers/graphql/test/src/test/java/org/apache/causeway/viewer/graphql/viewer/test/e2e/Domain_IntegTest.java
index d454b5b375..1bf7d53fa1 100644
---
a/incubator/viewers/graphql/test/src/test/java/org/apache/causeway/viewer/graphql/viewer/test/e2e/Domain_IntegTest.java
+++
b/incubator/viewers/graphql/test/src/test/java/org/apache/causeway/viewer/graphql/viewer/test/e2e/Domain_IntegTest.java
@@ -27,6 +27,7 @@ import javax.inject.Inject;
import org.apache.causeway.applib.services.bookmark.Bookmark;
import org.apache.causeway.applib.services.bookmark.BookmarkService;
+import org.apache.causeway.commons.internal.collections._Maps;
import org.apache.causeway.viewer.graphql.viewer.test.domain.StaffMember;
import
org.apache.causeway.viewer.graphql.viewer.test.domain.StaffMemberRepository;
@@ -184,6 +185,26 @@ public class Domain_IntegTest extends
CausewayViewerGraphqlTestModuleIntegTestAb
Approvals.verify(submit(), jsonOptions());
}
+ @Test
+ @UseReporter(DiffReporter.class)
+ void create_staff_member_with_department() throws Exception {
+
+ final Bookmark bookmark =
+ transactionService.callTransactional(
+ Propagation.REQUIRED,
+ () -> {
+ Department department =
departmentRepository.findByName("Classics");
+ return
bookmarkService.bookmarkFor(department).orElseThrow();
+ }
+ ).valueAsNonNullElseFail();
+
+ val response = submit(_Maps.unmodifiable("$departmentId",
bookmark.getIdentifier()));
+
+ // then payload
+ Approvals.verify(response, jsonOptions());
+
+ }
+
@Test
@UseReporter(DiffReporter.class)
void create_department() throws Exception {