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 {
