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 42580678d8da23e54fcaff1e21774fe12bf58477
Author: danhaywood <[email protected]>
AuthorDate: Fri Jan 26 13:06:06 2024 +0000

    CAUSEWAY-3676: adds support for collection params
---
 .../viewer/graphql/model/domain/GqlvAction.java    | 50 +++++++++++++++++-----
 ...ayViewerGraphqlTestModuleIntegTestAbstract.java |  9 ++++
 .../graphql/viewer/test/domain/Department.java     |  3 +-
 ..._department_and_add_staff_members._.choices.gql | 22 ++++++++++
 ...d_department_and_add_staff_members._.invoke.gql | 22 ++++++++++
 ..._department_and_add_staff_members.approved.json | 36 ++++++++++++++++
 .../graphql/viewer/test/e2e/Domain_IntegTest.java  | 37 +++++++++++++++-
 7 files changed, 167 insertions(+), 12 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 e99ac54172..04bf02b77b 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
@@ -36,7 +36,9 @@ import graphql.schema.*;
 import lombok.extern.log4j.Log4j2;
 import lombok.val;
 
+import java.util.List;
 import java.util.Map;
+import java.util.Objects;
 import java.util.Optional;
 import java.util.stream.Collectors;
 
@@ -101,23 +103,26 @@ public class GqlvAction
                     switch (elementType.getBeanSort()) {
 
                         case VALUE:
+                            // TODO: handle lists of values.
                             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));
+                            Object pojoOrPojoList;
+                            if (argumentValue instanceof List) {
+                                val argumentValueList = (List<Object>) 
argumentValue;
+                                pojoOrPojoList = argumentValueList.stream()
+                                        .map(value -> 
asPojo(oap.getElementType(), value, bookmarkService))
+                                        .filter(Optional::isPresent)
+                                        .map(Optional::get)
+                                        .collect(Collectors.toList());
+                            } else {
+                                pojoOrPojoList = asPojo(oap.getElementType(), 
argumentValue, bookmarkService).orElse(null);
+                            }
+                            return ManagedObject.adaptParameter(oap, 
pojoOrPojoList);
 
                         case ABSTRACT:
                         case COLLECTION:
@@ -133,6 +138,31 @@ public class GqlvAction
                 });
     }
 
+    private static ManagedObject asDomainObject(
+            final ObjectSpecification elementType,
+            final ObjectActionParameter oap,
+            final Object argumentValueObj,
+            final BookmarkService bookmarkService) {
+        return asPojo(elementType, argumentValueObj, bookmarkService)
+                .map(pojo -> ManagedObject.adaptParameter(oap, pojo))
+                .orElse(ManagedObject.empty(elementType));
+    }
+
+    private static Optional<Object> asPojo(
+            final ObjectSpecification elementType,
+            final Object argumentValueObj,
+            final BookmarkService bookmarkService) {
+        val argumentValue = (Map<String, String>) argumentValueObj;
+        String idValue = 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)
+;
+    }
+
     static void addGqlArguments(
             final ObjectAction objectAction,
             final GraphQLFieldDefinition.Builder builder,
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 1496364764..7e40dae0ae 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
@@ -165,6 +165,15 @@ public abstract class 
CausewayViewerGraphqlTestModuleIntegTestAbstract {
         return submitRequest(httpRequest);
     }
 
+    protected String submit(String variant) throws Exception{
+        return submit(variant, Collections.emptyMap());
+    }
+
+    protected String submit(String variant, Map<String,String> replacements) 
throws Exception{
+        val httpRequest = buildRequest(testInfo, "._." +variant + ".gql", 
replacements);
+        return submitRequest(httpRequest);
+    }
+
     @Value
     protected static class GqlBody {
         String query;
diff --git 
a/incubator/viewers/graphql/test/src/test/java/org/apache/causeway/viewer/graphql/viewer/test/domain/Department.java
 
b/incubator/viewers/graphql/test/src/test/java/org/apache/causeway/viewer/graphql/viewer/test/domain/Department.java
index d03c2b99e2..aa1275350e 100644
--- 
a/incubator/viewers/graphql/test/src/test/java/org/apache/causeway/viewer/graphql/viewer/test/domain/Department.java
+++ 
b/incubator/viewers/graphql/test/src/test/java/org/apache/causeway/viewer/graphql/viewer/test/domain/Department.java
@@ -161,8 +161,9 @@ public class Department implements Comparable<Department> {
         public Department act(List<StaffMember> staffMembers) {
             val department = Department.this;
 
-            department.staffMembers.addAll(staffMembers);
             staffMembers.forEach(sm -> sm.setDepartment(department));
+            department.staffMembers.addAll(staffMembers);
+
             return department;
         }
         public List<StaffMember> choices0Act() {
diff --git 
a/incubator/viewers/graphql/test/src/test/java/org/apache/causeway/viewer/graphql/viewer/test/e2e/Domain_IntegTest.find_department_and_add_staff_members._.choices.gql
 
b/incubator/viewers/graphql/test/src/test/java/org/apache/causeway/viewer/graphql/viewer/test/e2e/Domain_IntegTest.find_department_and_add_staff_members._.choices.gql
new file mode 100644
index 0000000000..ca9a1d7785
--- /dev/null
+++ 
b/incubator/viewers/graphql/test/src/test/java/org/apache/causeway/viewer/graphql/viewer/test/e2e/Domain_IntegTest.find_department_and_add_staff_members._.choices.gql
@@ -0,0 +1,22 @@
+{
+  university_dept_Departments {
+    findByName {
+      invoke(name: "Classics") {
+        addStaffMembers {
+          params {
+            staffMembers {
+              choices {
+                _gql_meta {
+                  id
+                }
+                name {
+                  get
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+}
diff --git 
a/incubator/viewers/graphql/test/src/test/java/org/apache/causeway/viewer/graphql/viewer/test/e2e/Domain_IntegTest.find_department_and_add_staff_members._.invoke.gql
 
b/incubator/viewers/graphql/test/src/test/java/org/apache/causeway/viewer/graphql/viewer/test/e2e/Domain_IntegTest.find_department_and_add_staff_members._.invoke.gql
new file mode 100644
index 0000000000..899406964d
--- /dev/null
+++ 
b/incubator/viewers/graphql/test/src/test/java/org/apache/causeway/viewer/graphql/viewer/test/e2e/Domain_IntegTest.find_department_and_add_staff_members._.invoke.gql
@@ -0,0 +1,22 @@
+{
+  university_dept_Departments {
+    findByName {
+      invoke(name: "Classics") {
+        addStaffMembers {
+          invokeIdempotent(staffMembers: [{id: "$staffMemberId1"}, {id: 
"$staffMemberId2"}]) {
+            name {
+              get
+            }
+            staffMembers {
+              get {
+                name {
+                  get
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+}
diff --git 
a/incubator/viewers/graphql/test/src/test/java/org/apache/causeway/viewer/graphql/viewer/test/e2e/Domain_IntegTest.find_department_and_add_staff_members.approved.json
 
b/incubator/viewers/graphql/test/src/test/java/org/apache/causeway/viewer/graphql/viewer/test/e2e/Domain_IntegTest.find_department_and_add_staff_members.approved.json
new file mode 100644
index 0000000000..a2fa305574
--- /dev/null
+++ 
b/incubator/viewers/graphql/test/src/test/java/org/apache/causeway/viewer/graphql/viewer/test/e2e/Domain_IntegTest.find_department_and_add_staff_members.approved.json
@@ -0,0 +1,36 @@
+{
+  "data" : {
+    "university_dept_Departments" : {
+      "findByName" : {
+        "invoke" : {
+          "addStaffMembers" : {
+            "invokeIdempotent" : {
+              "name" : {
+                "get" : "Classics"
+              },
+              "staffMembers" : {
+                "get" : [ {
+                  "name" : {
+                    "get" : "Gerry Jones"
+                  }
+                }, {
+                  "name" : {
+                    "get" : "John Gartner"
+                  }
+                }, {
+                  "name" : {
+                    "get" : "Letitia Leadbetter"
+                  }
+                }, {
+                  "name" : {
+                    "get" : "Mervin Hughes"
+                  }
+                } ]
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+}
\ 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 4bb2648632..bf73968c5f 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
@@ -20,13 +20,16 @@ package org.apache.causeway.viewer.graphql.viewer.test.e2e;
 
 import lombok.val;
 
+import java.util.ArrayList;
 import java.util.List;
+import java.util.Map;
 import java.util.Optional;
 
 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.base._Strings;
 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;
@@ -50,6 +53,9 @@ import 
org.apache.causeway.viewer.graphql.viewer.test.domain.DepartmentRepositor
 import org.apache.causeway.viewer.graphql.viewer.test.domain.DeptHead;
 import 
org.apache.causeway.viewer.graphql.viewer.test.domain.DeptHeadRepository;
 
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
 import static 
org.apache.causeway.commons.internal.assertions._Assert.assertEquals;
 import static 
org.apache.causeway.commons.internal.assertions._Assert.assertTrue;
 
@@ -86,7 +92,7 @@ public class Domain_IntegTest extends 
CausewayViewerGraphqlTestModuleIntegTestAb
             staffMemberRepository.create("Letitia Leadbetter", classics);
             staffMemberRepository.create("Gerry Jones", classics);
             staffMemberRepository.create("Mervin Hughes", physics);
-            staffMemberRepository.create("John Gaffney", physics);
+            staffMemberRepository.create("John Gartner", physics);
             staffMemberRepository.create("Margaret Randall", physics);
 
         });
@@ -173,6 +179,35 @@ public class Domain_IntegTest extends 
CausewayViewerGraphqlTestModuleIntegTestAb
         Approvals.verify(submit(), jsonOptions());
     }
 
+    @Test
+    @UseReporter(DiffReporter.class)
+    void find_department_and_add_staff_members() throws Exception {
+
+        // when, then
+        String submit = submit("choices");
+
+        ObjectMapper mapper = new ObjectMapper();
+        JsonNode root = mapper.readTree(submit);
+
+        JsonNode staffMembersNode = 
root.at("/data/university_dept_Departments/findByName/invoke/addStaffMembers/params/staffMembers/choices");
+
+        List<String> ids = new ArrayList<>();
+        staffMembersNode.forEach(staffMemberNode -> {
+            String id = staffMemberNode.get("_gql_meta").get("id").asText();
+            if (!_Strings.isNullOrEmpty(id)) {
+                ids.add(id);
+            }
+        });
+
+        Assertions.assertThat(ids).hasSize(3);
+
+        val replacements = _Maps.unmodifiable(
+                                "$staffMemberId1", ids.get(0),
+                                "$staffMemberId2", ids.get(1));
+
+        Approvals.verify(submit("invoke", replacements), jsonOptions());
+    }
+
     @Test
     @UseReporter(DiffReporter.class)
     void find_staff_member_by_name_and_edit() throws Exception {

Reply via email to