This is an automated email from the ASF dual-hosted git repository. danhaywood pushed a commit to branch CAUSEWAY-3718 in repository https://gitbox.apache.org/repos/asf/causeway.git
commit bdbef1770b9833d2368af77de1e2d47ed09adf5d Author: danhaywood <[email protected]> AuthorDate: Sat Apr 6 12:52:41 2024 +0100 CAUSEWAY-3718: reworks and extens integ tests for REST API (hilevel and lolevel) --- .../client/ActionParameterListBuilder.java | 45 +++- .../restfulobjects/client/RestfulClient.java | 2 +- .../restfulobjects/test/domain/dom/Staff.java | 11 + ...IntegTest.can_create_staff_member.approved.json | 109 -------- .../test/scenarios/staff/Staff_IntegTest.java | 102 -------- ...egTest.createStaffMemberWithPhoto.approved.json | 17 ++ ...gTest.createStaffMemberWithPhoto2.approved.json | 17 ++ ...teStaffMemberWithPhoto2_using_map.approved.json | 17 ++ ...ateStaffMemberWithPhoto_using_map.approved.json | 17 ++ .../scenarios/staff/Staff_hilevel_IntegTest.java | 278 +++++++++++++++++++++ ...gTest.createStaffMemberWithPhoto2.approved.json | 13 + ...gTest.java => Staff_lowlevel_v1_IntegTest.java} | 57 +++-- ...gTest.createStaffMemberWithPhoto2.approved.json | 17 ++ ...gTest.java => Staff_lowlevel_v2_IntegTest.java} | 83 +++--- 14 files changed, 507 insertions(+), 278 deletions(-) diff --git a/viewers/restfulobjects/client/src/main/java/org/apache/causeway/viewer/restfulobjects/client/ActionParameterListBuilder.java b/viewers/restfulobjects/client/src/main/java/org/apache/causeway/viewer/restfulobjects/client/ActionParameterListBuilder.java index a2223b4d21..21b69bb098 100644 --- a/viewers/restfulobjects/client/src/main/java/org/apache/causeway/viewer/restfulobjects/client/ActionParameterListBuilder.java +++ b/viewers/restfulobjects/client/src/main/java/org/apache/causeway/viewer/restfulobjects/client/ActionParameterListBuilder.java @@ -24,6 +24,8 @@ import java.util.stream.Collectors; import javax.ws.rs.client.Entity; +import org.apache.causeway.applib.services.bookmark.Bookmark; + import org.springframework.lang.Nullable; import org.apache.causeway.applib.util.schema.CommonDtoUtils; @@ -49,6 +51,19 @@ public class ActionParameterListBuilder { @Getter private final Map<String, Class<?>> actionParameterTypes = new LinkedHashMap<>(); + private final RestfulClient restfulClient; + + /** + * @deprecated - use {@link RestfulClient#arguments()} + */ + @Deprecated + public ActionParameterListBuilder() { + this(null); + } + public ActionParameterListBuilder(RestfulClient restfulClient) { + this.restfulClient = restfulClient; + } + public ActionParameterListBuilder addActionParameter(final String parameterName, final String parameterValue) { actionParameters.put(parameterName, parameterValue != null ? value("\"" + parameterValue + "\"") @@ -133,7 +148,35 @@ public class ActionParameterListBuilder { return this; } - public <T> ActionParameterListBuilder addActionParameter(final String parameterName, + public ActionParameterListBuilder addActionParameter( + final @NonNull String parameterName, + final @NonNull Bookmark bookmark) { + if (this.restfulClient == null) { + throw new IllegalStateException("Use RestfulClient#arguments() to create this builder"); + } + actionParameters.put(parameterName, valueHref( bookmark) ); + actionParameterTypes.put(parameterName, Map.class); + return this; + } + + private String valueHref(Bookmark bookmark) { + String hrefValue = asAbsoluteHref(bookmark); +// String hrefValue = "\"" + asAbsoluteHref(bookmark) + "\""; + Map<String, String> map = Map.of("href", hrefValue); + return value(JsonUtils.toStringUtf8(map)); + } + + private String asAbsoluteHref(Bookmark bookmark) { + return String.format("%s%s", restfulClient.getConfig().getRestfulBaseUrl(), asRelativeHref(bookmark)); + } + + private String asRelativeHref(Bookmark bookmark) { + return String.format("objects/%s/%s", bookmark.getLogicalTypeName(), bookmark.getIdentifier()); + } + + + public <T> ActionParameterListBuilder addActionParameter( + final String parameterName, final @NonNull Class<T> type, final @Nullable T object) { var nestedJson = object!=null diff --git a/viewers/restfulobjects/client/src/main/java/org/apache/causeway/viewer/restfulobjects/client/RestfulClient.java b/viewers/restfulobjects/client/src/main/java/org/apache/causeway/viewer/restfulobjects/client/RestfulClient.java index 97134fbe57..7c7f3cf60d 100644 --- a/viewers/restfulobjects/client/src/main/java/org/apache/causeway/viewer/restfulobjects/client/RestfulClient.java +++ b/viewers/restfulobjects/client/src/main/java/org/apache/causeway/viewer/restfulobjects/client/RestfulClient.java @@ -172,7 +172,7 @@ public class RestfulClient implements AutoCloseable { // -- ARGUMENT BUILDER public ActionParameterListBuilder arguments() { - return new ActionParameterListBuilder(); + return new ActionParameterListBuilder(this); } // -- RESPONSE PROCESSING diff --git a/viewers/restfulobjects/test/src/test/java/org/apache/causeway/viewer/restfulobjects/test/domain/dom/Staff.java b/viewers/restfulobjects/test/src/test/java/org/apache/causeway/viewer/restfulobjects/test/domain/dom/Staff.java index 794cdb3c17..37d394023a 100644 --- a/viewers/restfulobjects/test/src/test/java/org/apache/causeway/viewer/restfulobjects/test/domain/dom/Staff.java +++ b/viewers/restfulobjects/test/src/test/java/org/apache/causeway/viewer/restfulobjects/test/domain/dom/Staff.java @@ -60,6 +60,17 @@ public class Staff { return staffMember; } + @Action(semantics = SemanticsOf.NON_IDEMPOTENT) + public StaffMember createStaffMemberWithPhoto2( + final String name, + final Department department, + final Blob photo + ){ + final var staffMember = createStaffMember(name, department); + staffMember.setPhoto(photo); + return staffMember; + } + @Action(semantics = SemanticsOf.SAFE) public List<StaffMember> findAllStaffMembers(){ return staffMemberRepository.findAll(); diff --git a/viewers/restfulobjects/test/src/test/java/org/apache/causeway/viewer/restfulobjects/test/scenarios/staff/Staff_IntegTest.can_create_staff_member.approved.json b/viewers/restfulobjects/test/src/test/java/org/apache/causeway/viewer/restfulobjects/test/scenarios/staff/Staff_IntegTest.can_create_staff_member.approved.json deleted file mode 100644 index d5143d4cd6..0000000000 --- a/viewers/restfulobjects/test/src/test/java/org/apache/causeway/viewer/restfulobjects/test/scenarios/staff/Staff_IntegTest.can_create_staff_member.approved.json +++ /dev/null @@ -1,109 +0,0 @@ -{ - "links" : [ { - "rel" : "self", - "href" : "http://0.0.0.0:NNN/restful/objects/university.dept.StaffMember/NNN", - "method" : "GET", - "type" : "application/json;profile=\"urn:org.restfulobjects:repr-types/object\"", - "title" : "Untitled Staff Member" - }, { - "rel" : "describedby", - "href" : "http://0.0.0.0:NNN/restful/domain-types/university.dept.StaffMember", - "method" : "GET", - "type" : "application/json;profile=\"urn:org.restfulobjects:repr-types/domain-type\"" - }, { - "rel" : "urn:org.apache.causeway.restfulobjects:rels/object-layout", - "href" : "http://0.0.0.0:NNN/restful/objects/university.dept.StaffMember/NNN/object-layout", - "method" : "GET", - "type" : "application/json;profile=\"urn:org.restfulobjects:repr-types/object-layout-bs\"" - }, { - "rel" : "urn:org.apache.causeway.restfulobjects:rels/object-icon", - "href" : "http://0.0.0.0:NNN/restful/objects/university.dept.StaffMember/NNN/object-icon", - "method" : "GET", - "type" : "image/*" - }, { - "rel" : "urn:org.restfulobjects:rels/update", - "href" : "http://0.0.0.0:NNN/restful/objects/university.dept.StaffMember:NNN", - "method" : "PUT", - "type" : "application/json;profile=\"urn:org.restfulobjects:repr-types/object\"", - "arguments" : { } - } ], - "extensions" : { - "oid" : "university.dept.StaffMember:NNN", - "isService" : false, - "isPersistent" : true - }, - "title" : "Untitled Staff Member", - "domainType" : "university.dept.StaffMember", - "instanceId" : "NNN", - "members" : { - "department" : { - "id" : "department", - "memberType" : "property", - "links" : [ { - "rel" : "urn:org.restfulobjects:rels/details;property=\"department\"", - "href" : "http://0.0.0.0:NNN/restful/objects/university.dept.StaffMember/NNN/properties/department", - "method" : "GET", - "type" : "application/json;profile=\"urn:org.restfulobjects:repr-types/object-property\"" - } ], - "value" : { - "rel" : "urn:org.restfulobjects:rels/value", - "href" : "http://0.0.0.0:NNN/restful/objects/university.dept.Department/NNN", - "method" : "GET", - "type" : "application/json;profile=\"urn:org.restfulobjects:repr-types/object\"", - "title" : "Untitled Department" - }, - "disabledReason" : "Disabled via @DomainObject annotation, reason not given." - }, - "grade" : { - "id" : "grade", - "memberType" : "property", - "links" : [ { - "rel" : "urn:org.restfulobjects:rels/details;property=\"grade\"", - "href" : "http://0.0.0.0:NNN/restful/objects/university.dept.StaffMember/NNN/properties/grade", - "method" : "GET", - "type" : "application/json;profile=\"urn:org.restfulobjects:repr-types/object-property\"" - } ], - "value" : { - "enumType" : "org.apache.causeway.viewer.restfulobjects.test.domain.dom.Grade", - "enumName" : "LECTURER", - "enumTitle" : "Lecturer" - }, - "extensions" : { - "x-causeway-format" : "enum" - } - }, - "name" : { - "id" : "name", - "memberType" : "property", - "links" : [ { - "rel" : "urn:org.restfulobjects:rels/details;property=\"name\"", - "href" : "http://0.0.0.0:NNN/restful/objects/university.dept.StaffMember/NNN/properties/name", - "method" : "GET", - "type" : "application/json;profile=\"urn:org.restfulobjects:repr-types/object-property\"" - } ], - "value" : "Fred Smith", - "extensions" : { - "x-causeway-format" : "string" - } - }, - "photo" : { - "id" : "photo", - "memberType" : "property", - "links" : [ { - "rel" : "urn:org.restfulobjects:rels/details;property=\"photo\"", - "href" : "http://0.0.0.0:NNN/restful/objects/university.dept.StaffMember/NNN/properties/photo", - "method" : "GET", - "type" : "application/json;profile=\"urn:org.restfulobjects:repr-types/object-property\"" - } ], - "value" : { - "name" : "StaffMember-photo-Bar.pdf", - "mimeType" : "application/pdf", - "bytes" : "JVBERi0xLjcNCiW1tbW1DQoxIDAgb2JqDQo8PC9UeXBlL0NhdGFsb2cvUGFnZXMgMiAwIFIvTGFuZyhlbi1HQikgL1N0cnVjdFRyZWVSb290IDEyIDAgUi9NYXJrSW5mbzw8L01hcmtlZCB0cnVlPj4vTWV0YWRhdGEgMzIgMCBSL1ZpZXdlclByZWZlcmVuY2VzIDMzIDAgUj4+DQplbmRvYmoNCjIgMCBvYmoNCjw8L1R5cGUvUGFnZXMvQ291bnQgMS9LaWRzWyAzIDAgUl0gPj4NCmVuZG9iag0KMyAwIG9iag0KPDwvVHlwZS9QYWdlL1BhcmVudCAyIDAgUi9SZXNvdXJjZXM8PC9Gb250PDwvRjEgNSAwIFIvRjIgOSAwIFI+Pi9FeHRHU3RhdGU8PC9HUzcgNyAwIFIvR1M4IDggMCBSPj4vUHJvY1NldFsvUERGL1RleHQvSW1hZ2VCL [...] - }, - "extensions" : { - "x-causeway-format" : "blob" - }, - "disabledReason" : "Disabled via @DomainObject annotation, reason not given." - } - } -} \ No newline at end of file diff --git a/viewers/restfulobjects/test/src/test/java/org/apache/causeway/viewer/restfulobjects/test/scenarios/staff/Staff_IntegTest.java b/viewers/restfulobjects/test/src/test/java/org/apache/causeway/viewer/restfulobjects/test/scenarios/staff/Staff_IntegTest.java deleted file mode 100644 index 316fdb2e1e..0000000000 --- a/viewers/restfulobjects/test/src/test/java/org/apache/causeway/viewer/restfulobjects/test/scenarios/staff/Staff_IntegTest.java +++ /dev/null @@ -1,102 +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.restfulobjects.test.scenarios.staff; - -import javax.ws.rs.core.Response; - -import org.approvaltests.Approvals; -import org.approvaltests.reporters.DiffReporter; -import org.approvaltests.reporters.UseReporter; -import org.junit.jupiter.api.Test; - -import static org.assertj.core.api.Assertions.assertThat; - -import org.springframework.transaction.annotation.Propagation; - -import org.apache.causeway.applib.value.Blob; -import org.apache.causeway.applib.value.NamedWithMimeType.CommonMimeType; -import org.apache.causeway.commons.io.DataSource; -import org.apache.causeway.viewer.restfulobjects.test.domain.dom.Department; -import org.apache.causeway.viewer.restfulobjects.test.scenarios.Abstract_IntegTest; - -import lombok.SneakyThrows; -import lombok.val; - -class Staff_IntegTest extends Abstract_IntegTest { - - @SneakyThrows - @Test - @UseReporter(DiffReporter.class) - public void can_create_staff_member() { - - // given - final var staffName = "Fred Smith"; - - final var bookmarkBeforeIfAny = transactionService.callTransactional(Propagation.REQUIRED, () -> { - final var staffMember = staffMemberRepository.findByName(staffName); - return bookmarkService.bookmarkFor(staffMember); - }).valueAsNonNullElseFail(); - - assertThat(bookmarkBeforeIfAny).isEmpty(); - - final Blob photo = readFileAsBlob("StaffMember-photo-Bar.pdf"); - final var requestBuilder = restfulClient.request("services/university.dept.Staff/actions/createStaffMemberWithPhoto/invoke"); - - /* - * String name, - * Department.SecondaryKey departmentSecondaryKey, - * Blob photo - */ - var args = restfulClient.arguments() - .addActionParameter("name", staffName) - //.addActionParameter("departmentSecondaryKey", Map.of("name", "Classics")) ... can be used alternatively - .addActionParameter("departmentSecondaryKey", Department.SecondaryKey.class, new Department.SecondaryKey("Classics")) - .addActionParameter("photo", photo) - .build(); - - // when - val response = requestBuilder.post(args); - - // then - assertThat(response.getStatusInfo().getFamily()).isEqualTo(Response.Status.Family.SUCCESSFUL); - assertThat(response.getStatus()).isEqualTo(Response.Status.OK.getStatusCode()); - - // and also json response - val entity = response.readEntity(String.class); - assertThat(response) - .extracting(Response::getStatus) - .isEqualTo(Response.Status.OK.getStatusCode()); - Approvals.verify(entity, jsonOptions()); - - // and also object is created in database - final var bookmarkAfterIfAny = transactionService.callTransactional(Propagation.REQUIRED, () -> { - final var staffMember = staffMemberRepository.findByName(staffName); - return bookmarkService.bookmarkFor(staffMember); - }).valueAsNonNullElseFail(); - assertThat(bookmarkAfterIfAny).isNotEmpty(); - } - - private Blob readFileAsBlob(final String fileName) { - var bytes = DataSource.ofResource(Abstract_IntegTest.class, fileName) - .bytes(); - return Blob.of(fileName, CommonMimeType.PDF, bytes); - } - -} - diff --git a/viewers/restfulobjects/test/src/test/java/org/apache/causeway/viewer/restfulobjects/test/scenarios/staff/Staff_hilevel_IntegTest.createStaffMemberWithPhoto.approved.json b/viewers/restfulobjects/test/src/test/java/org/apache/causeway/viewer/restfulobjects/test/scenarios/staff/Staff_hilevel_IntegTest.createStaffMemberWithPhoto.approved.json new file mode 100644 index 0000000000..4b6928e173 --- /dev/null +++ b/viewers/restfulobjects/test/src/test/java/org/apache/causeway/viewer/restfulobjects/test/scenarios/staff/Staff_hilevel_IntegTest.createStaffMemberWithPhoto.approved.json @@ -0,0 +1,17 @@ +{ + "name" : { + "value" : "Fred Smith" + }, + "departmentSecondaryKey" : { + "value" : { + "name" : "Classics" + } + }, + "photo" : { + "value" : { + "name" : "StaffMember-photo-Bar.pdf", + "mimeType" : "application/pdf", + "bytes" : "JVBERi0xLjcNCiW1tbW1DQoxIDAgb2JqDQo8PC9UeXBlL0NhdGFsb2cvUGFnZXMgMiAwIFIvTGFuZyhlbi1HQikgL1N0cnVjdFRyZWVSb290IDEyIDAgUi9NYXJrSW5mbzw8L01hcmtlZCB0cnVlPj4vTWV0YWRhdGEgMzIgMCBSL1ZpZXdlclByZWZlcmVuY2VzIDMzIDAgUj4+DQplbmRvYmoNCjIgMCBvYmoNCjw8L1R5cGUvUGFnZXMvQ291bnQgMS9LaWRzWyAzIDAgUl0gPj4NCmVuZG9iag0KMyAwIG9iag0KPDwvVHlwZS9QYWdlL1BhcmVudCAyIDAgUi9SZXNvdXJjZXM8PC9Gb250PDwvRjEgNSAwIFIvRjIgOSAwIFI+Pi9FeHRHU3RhdGU8PC9HUzcgNyAwIFIvR1M4IDggMCBSPj4vUHJvY1NldFsvUERGL1RleHQvSW1hZ2VCL0l [...] + } + } +} \ No newline at end of file diff --git a/viewers/restfulobjects/test/src/test/java/org/apache/causeway/viewer/restfulobjects/test/scenarios/staff/Staff_hilevel_IntegTest.createStaffMemberWithPhoto2.approved.json b/viewers/restfulobjects/test/src/test/java/org/apache/causeway/viewer/restfulobjects/test/scenarios/staff/Staff_hilevel_IntegTest.createStaffMemberWithPhoto2.approved.json new file mode 100644 index 0000000000..a6123f9fb9 --- /dev/null +++ b/viewers/restfulobjects/test/src/test/java/org/apache/causeway/viewer/restfulobjects/test/scenarios/staff/Staff_hilevel_IntegTest.createStaffMemberWithPhoto2.approved.json @@ -0,0 +1,17 @@ +{ + "name" : { + "value" : "Fred Smith" + }, + "department" : { + "value" : { + "href" : "http://0.0.0.0:NNN/restful/objects/university.dept.Department/NNN" + } + }, + "photo" : { + "value" : { + "name" : "StaffMember-photo-Bar.pdf", + "mimeType" : "application/pdf", + "bytes" : "JVBERi0xLjcNCiW1tbW1DQoxIDAgb2JqDQo8PC9UeXBlL0NhdGFsb2cvUGFnZXMgMiAwIFIvTGFuZyhlbi1HQikgL1N0cnVjdFRyZWVSb290IDEyIDAgUi9NYXJrSW5mbzw8L01hcmtlZCB0cnVlPj4vTWV0YWRhdGEgMzIgMCBSL1ZpZXdlclByZWZlcmVuY2VzIDMzIDAgUj4+DQplbmRvYmoNCjIgMCBvYmoNCjw8L1R5cGUvUGFnZXMvQ291bnQgMS9LaWRzWyAzIDAgUl0gPj4NCmVuZG9iag0KMyAwIG9iag0KPDwvVHlwZS9QYWdlL1BhcmVudCAyIDAgUi9SZXNvdXJjZXM8PC9Gb250PDwvRjEgNSAwIFIvRjIgOSAwIFI+Pi9FeHRHU3RhdGU8PC9HUzcgNyAwIFIvR1M4IDggMCBSPj4vUHJvY1NldFsvUERGL1RleHQvSW1hZ2VCL0l [...] + } + } +} \ No newline at end of file diff --git a/viewers/restfulobjects/test/src/test/java/org/apache/causeway/viewer/restfulobjects/test/scenarios/staff/Staff_hilevel_IntegTest.createStaffMemberWithPhoto2_using_map.approved.json b/viewers/restfulobjects/test/src/test/java/org/apache/causeway/viewer/restfulobjects/test/scenarios/staff/Staff_hilevel_IntegTest.createStaffMemberWithPhoto2_using_map.approved.json new file mode 100644 index 0000000000..a6123f9fb9 --- /dev/null +++ b/viewers/restfulobjects/test/src/test/java/org/apache/causeway/viewer/restfulobjects/test/scenarios/staff/Staff_hilevel_IntegTest.createStaffMemberWithPhoto2_using_map.approved.json @@ -0,0 +1,17 @@ +{ + "name" : { + "value" : "Fred Smith" + }, + "department" : { + "value" : { + "href" : "http://0.0.0.0:NNN/restful/objects/university.dept.Department/NNN" + } + }, + "photo" : { + "value" : { + "name" : "StaffMember-photo-Bar.pdf", + "mimeType" : "application/pdf", + "bytes" : "JVBERi0xLjcNCiW1tbW1DQoxIDAgb2JqDQo8PC9UeXBlL0NhdGFsb2cvUGFnZXMgMiAwIFIvTGFuZyhlbi1HQikgL1N0cnVjdFRyZWVSb290IDEyIDAgUi9NYXJrSW5mbzw8L01hcmtlZCB0cnVlPj4vTWV0YWRhdGEgMzIgMCBSL1ZpZXdlclByZWZlcmVuY2VzIDMzIDAgUj4+DQplbmRvYmoNCjIgMCBvYmoNCjw8L1R5cGUvUGFnZXMvQ291bnQgMS9LaWRzWyAzIDAgUl0gPj4NCmVuZG9iag0KMyAwIG9iag0KPDwvVHlwZS9QYWdlL1BhcmVudCAyIDAgUi9SZXNvdXJjZXM8PC9Gb250PDwvRjEgNSAwIFIvRjIgOSAwIFI+Pi9FeHRHU3RhdGU8PC9HUzcgNyAwIFIvR1M4IDggMCBSPj4vUHJvY1NldFsvUERGL1RleHQvSW1hZ2VCL0l [...] + } + } +} \ No newline at end of file diff --git a/viewers/restfulobjects/test/src/test/java/org/apache/causeway/viewer/restfulobjects/test/scenarios/staff/Staff_hilevel_IntegTest.createStaffMemberWithPhoto_using_map.approved.json b/viewers/restfulobjects/test/src/test/java/org/apache/causeway/viewer/restfulobjects/test/scenarios/staff/Staff_hilevel_IntegTest.createStaffMemberWithPhoto_using_map.approved.json new file mode 100644 index 0000000000..4b6928e173 --- /dev/null +++ b/viewers/restfulobjects/test/src/test/java/org/apache/causeway/viewer/restfulobjects/test/scenarios/staff/Staff_hilevel_IntegTest.createStaffMemberWithPhoto_using_map.approved.json @@ -0,0 +1,17 @@ +{ + "name" : { + "value" : "Fred Smith" + }, + "departmentSecondaryKey" : { + "value" : { + "name" : "Classics" + } + }, + "photo" : { + "value" : { + "name" : "StaffMember-photo-Bar.pdf", + "mimeType" : "application/pdf", + "bytes" : "JVBERi0xLjcNCiW1tbW1DQoxIDAgb2JqDQo8PC9UeXBlL0NhdGFsb2cvUGFnZXMgMiAwIFIvTGFuZyhlbi1HQikgL1N0cnVjdFRyZWVSb290IDEyIDAgUi9NYXJrSW5mbzw8L01hcmtlZCB0cnVlPj4vTWV0YWRhdGEgMzIgMCBSL1ZpZXdlclByZWZlcmVuY2VzIDMzIDAgUj4+DQplbmRvYmoNCjIgMCBvYmoNCjw8L1R5cGUvUGFnZXMvQ291bnQgMS9LaWRzWyAzIDAgUl0gPj4NCmVuZG9iag0KMyAwIG9iag0KPDwvVHlwZS9QYWdlL1BhcmVudCAyIDAgUi9SZXNvdXJjZXM8PC9Gb250PDwvRjEgNSAwIFIvRjIgOSAwIFI+Pi9FeHRHU3RhdGU8PC9HUzcgNyAwIFIvR1M4IDggMCBSPj4vUHJvY1NldFsvUERGL1RleHQvSW1hZ2VCL0l [...] + } + } +} \ No newline at end of file diff --git a/viewers/restfulobjects/test/src/test/java/org/apache/causeway/viewer/restfulobjects/test/scenarios/staff/Staff_hilevel_IntegTest.java b/viewers/restfulobjects/test/src/test/java/org/apache/causeway/viewer/restfulobjects/test/scenarios/staff/Staff_hilevel_IntegTest.java new file mode 100644 index 0000000000..b1e02c753f --- /dev/null +++ b/viewers/restfulobjects/test/src/test/java/org/apache/causeway/viewer/restfulobjects/test/scenarios/staff/Staff_hilevel_IntegTest.java @@ -0,0 +1,278 @@ +/* + * 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.restfulobjects.test.scenarios.staff; + +import javax.ws.rs.core.Response; + +import org.apache.causeway.applib.services.bookmark.Bookmark; + +import org.approvaltests.Approvals; +import org.approvaltests.reporters.DiffReporter; +import org.approvaltests.reporters.UseReporter; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.springframework.transaction.annotation.Propagation; + +import org.apache.causeway.applib.value.Blob; +import org.apache.causeway.applib.value.NamedWithMimeType.CommonMimeType; +import org.apache.causeway.commons.io.DataSource; +import org.apache.causeway.viewer.restfulobjects.test.domain.dom.Department; +import org.apache.causeway.viewer.restfulobjects.test.scenarios.Abstract_IntegTest; + +import lombok.SneakyThrows; +import lombok.val; + +import java.util.Map; + +class Staff_hilevel_IntegTest extends Abstract_IntegTest { + + @SneakyThrows + @Test + @UseReporter(DiffReporter.class) + public void createStaffMemberWithPhoto() { + + // given + final var staffName = "Fred Smith"; + + final var bookmarkBeforeIfAny = transactionService.callTransactional(Propagation.REQUIRED, () -> { + final var staffMember = staffMemberRepository.findByName(staffName); + return bookmarkService.bookmarkFor(staffMember); + }).valueAsNonNullElseFail(); + + assertThat(bookmarkBeforeIfAny).isEmpty(); + + final Blob photo = readFileAsBlob("StaffMember-photo-Bar.pdf"); + final var requestBuilder = restfulClient.request("services/university.dept.Staff/actions/createStaffMemberWithPhoto/invoke"); + + /* + * String name, + * Department.SecondaryKey departmentSecondaryKey, + * Blob photo + */ + var args = restfulClient.arguments() + .addActionParameter("name", staffName) + .addActionParameter("departmentSecondaryKey", Department.SecondaryKey.class, new Department.SecondaryKey("Classics")) + .addActionParameter("photo", photo) + .build(); + + Approvals.verify(args.getEntity(), jsonOptions()); + + // when + val response = requestBuilder.post(args); + + // then + assertThat(response.getStatusInfo().getFamily()).isEqualTo(Response.Status.Family.SUCCESSFUL); + assertThat(response.getStatus()).isEqualTo(Response.Status.OK.getStatusCode()); + + // and also json response + val entity = response.readEntity(String.class); + assertThat(response) + .extracting(Response::getStatus) + .isEqualTo(Response.Status.OK.getStatusCode()); + + // and also object is created in database + final var bookmarkAfterIfAny = transactionService.callTransactional(Propagation.REQUIRED, () -> { + final var staffMember = staffMemberRepository.findByName(staffName); + return bookmarkService.bookmarkFor(staffMember); + }).valueAsNonNullElseFail(); + assertThat(bookmarkAfterIfAny).isNotEmpty(); + } + + @SneakyThrows + @Test + @UseReporter(DiffReporter.class) + public void createStaffMemberWithPhoto_using_map() { + + // given + final var staffName = "Fred Smith"; + + final var bookmarkBeforeIfAny = transactionService.callTransactional(Propagation.REQUIRED, () -> { + final var staffMember = staffMemberRepository.findByName(staffName); + return bookmarkService.bookmarkFor(staffMember); + }).valueAsNonNullElseFail(); + + assertThat(bookmarkBeforeIfAny).isEmpty(); + + final Blob photo = readFileAsBlob("StaffMember-photo-Bar.pdf"); + final var requestBuilder = restfulClient.request("services/university.dept.Staff/actions/createStaffMemberWithPhoto/invoke"); + + var args = restfulClient.arguments() + .addActionParameter("name", staffName) + .addActionParameter("departmentSecondaryKey", Map.of("name", "Classics")) + .addActionParameter("photo", photo) + .build(); + + Approvals.verify(args.getEntity(), jsonOptions()); + + // when + val response = requestBuilder.post(args); + + // then + assertThat(response.getStatusInfo().getFamily()).isEqualTo(Response.Status.Family.SUCCESSFUL); + assertThat(response.getStatus()).isEqualTo(Response.Status.OK.getStatusCode()); + + // and also json response + val entity = response.readEntity(String.class); + assertThat(response) + .extracting(Response::getStatus) + .isEqualTo(Response.Status.OK.getStatusCode()); + + // and also object is created in database + final var bookmarkAfterIfAny = transactionService.callTransactional(Propagation.REQUIRED, () -> { + final var staffMember = staffMemberRepository.findByName(staffName); + return bookmarkService.bookmarkFor(staffMember); + }).valueAsNonNullElseFail(); + assertThat(bookmarkAfterIfAny).isNotEmpty(); + } + + @SneakyThrows + @Test + @UseReporter(DiffReporter.class) + public void createStaffMemberWithPhoto2() { + + // given + final var staffName = "Fred Smith"; + + final var bookmarkBeforeIfAny = transactionService.callTransactional(Propagation.REQUIRED, () -> { + final var staffMember = staffMemberRepository.findByName(staffName); + return bookmarkService.bookmarkFor(staffMember); + }).valueAsNonNullElseFail(); + + assertThat(bookmarkBeforeIfAny).isEmpty(); + + // and given + final var departmentName = "Classics"; + final var departmentBookmark = transactionService.callTransactional(Propagation.REQUIRED, () -> { + final var staffMember = departmentRepository.findByName(departmentName); + return bookmarkService.bookmarkFor(staffMember).orElseThrow(); + }).valueAsNonNullElseFail(); + + // and given + final Blob photo = readFileAsBlob("StaffMember-photo-Bar.pdf"); + final var requestBuilder = restfulClient.request("services/university.dept.Staff/actions/createStaffMemberWithPhoto2/invoke"); + + var args = restfulClient.arguments() + .addActionParameter("name", staffName) + .addActionParameter("department", departmentBookmark) + .addActionParameter("photo", photo) + .build(); + + Approvals.verify(args.getEntity(), jsonOptions()); + + // when + val response = requestBuilder.post(args); + + // then + assertThat(response.getStatusInfo().getFamily()).isEqualTo(Response.Status.Family.SUCCESSFUL); + assertThat(response.getStatus()).isEqualTo(Response.Status.OK.getStatusCode()); + + // and also json response + val entity = response.readEntity(String.class); + assertThat(response) + .extracting(Response::getStatus) + .isEqualTo(Response.Status.OK.getStatusCode()); + + // and also object is created in database + final var bookmarkAfterIfAny = transactionService.callTransactional(Propagation.REQUIRED, () -> { + final var staffMember = staffMemberRepository.findByName(staffName); + return bookmarkService.bookmarkFor(staffMember); + }).valueAsNonNullElseFail(); + assertThat(bookmarkAfterIfAny).isNotEmpty(); + } + + @SneakyThrows + @Test + @UseReporter(DiffReporter.class) + public void createStaffMemberWithPhoto2_using_map() { + + // given + final var staffName = "Fred Smith"; + + final var bookmarkBeforeIfAny = transactionService.callTransactional(Propagation.REQUIRED, () -> { + final var staffMember = staffMemberRepository.findByName(staffName); + return bookmarkService.bookmarkFor(staffMember); + }).valueAsNonNullElseFail(); + + assertThat(bookmarkBeforeIfAny).isEmpty(); + + // and given + final var departmentName = "Classics"; + final var departmentBookmark = transactionService.callTransactional(Propagation.REQUIRED, () -> { + final var staffMember = departmentRepository.findByName(departmentName); + return bookmarkService.bookmarkFor(staffMember).orElseThrow(); + }).valueAsNonNullElseFail(); + + // and given + final Blob photo = readFileAsBlob("StaffMember-photo-Bar.pdf"); + final var requestBuilder = restfulClient.request("services/university.dept.Staff/actions/createStaffMemberWithPhoto2/invoke"); + + /* + * String name, + * Department.SecondaryKey departmentSecondaryKey, + * Blob photo + */ + var args = restfulClient.arguments() + .addActionParameter("name", staffName) + .addActionParameter("department", Map.of("href", asAbsoluteHref(departmentBookmark))) + .addActionParameter("photo", photo) + .build(); + + Approvals.verify(args.getEntity(), jsonOptions()); + + // when + val response = requestBuilder.post(args); + + // then + assertThat(response.getStatusInfo().getFamily()).isEqualTo(Response.Status.Family.SUCCESSFUL); + assertThat(response.getStatus()).isEqualTo(Response.Status.OK.getStatusCode()); + + // and also json response + val entity = response.readEntity(String.class); + assertThat(response) + .extracting(Response::getStatus) + .isEqualTo(Response.Status.OK.getStatusCode()); + + // and also object is created in database + final var bookmarkAfterIfAny = transactionService.callTransactional(Propagation.REQUIRED, () -> { + final var staffMember = staffMemberRepository.findByName(staffName); + return bookmarkService.bookmarkFor(staffMember); + }).valueAsNonNullElseFail(); + assertThat(bookmarkAfterIfAny).isNotEmpty(); + } + + + private Blob readFileAsBlob(final String fileName) { + var bytes = DataSource.ofResource(Abstract_IntegTest.class, fileName) + .bytes(); + return Blob.of(fileName, CommonMimeType.PDF, bytes); + } + + private String asAbsoluteHref(Bookmark bookmark) { + return String.format("%s%s", restfulClient.getConfig().getRestfulBaseUrl(), asRelativeHref(bookmark)); + } + + private String asRelativeHref(Bookmark bookmark) { + return String.format("objects/%s/%s", bookmark.getLogicalTypeName(), bookmark.getIdentifier()); + } + + +} + diff --git a/viewers/restfulobjects/test/src/test/java/org/apache/causeway/viewer/restfulobjects/test/scenarios/staff/Staff_lowlevel_v1_IntegTest.createStaffMemberWithPhoto2.approved.json b/viewers/restfulobjects/test/src/test/java/org/apache/causeway/viewer/restfulobjects/test/scenarios/staff/Staff_lowlevel_v1_IntegTest.createStaffMemberWithPhoto2.approved.json new file mode 100644 index 0000000000..5c1d966721 --- /dev/null +++ b/viewers/restfulobjects/test/src/test/java/org/apache/causeway/viewer/restfulobjects/test/scenarios/staff/Staff_lowlevel_v1_IntegTest.createStaffMemberWithPhoto2.approved.json @@ -0,0 +1,13 @@ +{ + "name" : { + "value" : "Fred Smith" + }, + "department" : { + "value" : { + "href" : "http://0.0.0.0:NNN/restful/objects/university.dept.Department/NNN" + } + }, + "photo" : { + "value" : "StaffMember-photo-Bar.pdf:application/pdf:JVBERi0xLjcNCiW1tbW1DQoxIDAgb2JqDQo8PC9UeXBlL0NhdGFsb2cvUGFnZXMgMiAwIFIvTGFuZyhlbi1HQikgL1N0cnVjdFRyZWVSb290IDEyIDAgUi9NYXJrSW5mbzw8L01hcmtlZCB0cnVlPj4vTWV0YWRhdGEgMzIgMCBSL1ZpZXdlclByZWZlcmVuY2VzIDMzIDAgUj4+DQplbmRvYmoNCjIgMCBvYmoNCjw8L1R5cGUvUGFnZXMvQ291bnQgMS9LaWRzWyAzIDAgUl0gPj4NCmVuZG9iag0KMyAwIG9iag0KPDwvVHlwZS9QYWdlL1BhcmVudCAyIDAgUi9SZXNvdXJjZXM8PC9Gb250PDwvRjEgNSAwIFIvRjIgOSAwIFI+Pi9FeHRHU3RhdGU8PC9HUzcgNyAwIFIvR1M4IDggMCB [...] + } +} \ No newline at end of file diff --git a/viewers/restfulobjects/test/src/test/java/org/apache/causeway/viewer/restfulobjects/test/scenarios/staff/Staff_Orig_IntegTest.java b/viewers/restfulobjects/test/src/test/java/org/apache/causeway/viewer/restfulobjects/test/scenarios/staff/Staff_lowlevel_v1_IntegTest.java similarity index 82% copy from viewers/restfulobjects/test/src/test/java/org/apache/causeway/viewer/restfulobjects/test/scenarios/staff/Staff_Orig_IntegTest.java copy to viewers/restfulobjects/test/src/test/java/org/apache/causeway/viewer/restfulobjects/test/scenarios/staff/Staff_lowlevel_v1_IntegTest.java index cafae75234..150f332917 100644 --- a/viewers/restfulobjects/test/src/test/java/org/apache/causeway/viewer/restfulobjects/test/scenarios/staff/Staff_Orig_IntegTest.java +++ b/viewers/restfulobjects/test/src/test/java/org/apache/causeway/viewer/restfulobjects/test/scenarios/staff/Staff_lowlevel_v1_IntegTest.java @@ -29,6 +29,7 @@ import javax.ws.rs.core.Response; import com.google.common.io.Resources; import com.google.gson.GsonBuilder; +import org.approvaltests.Approvals; import org.approvaltests.reporters.DiffReporter; import org.approvaltests.reporters.UseReporter; import org.junit.jupiter.api.BeforeEach; @@ -45,7 +46,7 @@ import lombok.Getter; import lombok.SneakyThrows; import lombok.val; -public class Staff_Orig_IntegTest extends Abstract_IntegTest { +public class Staff_lowlevel_v1_IntegTest extends Abstract_IntegTest { private GsonBuilder gsonBuilder; @@ -57,7 +58,7 @@ public class Staff_Orig_IntegTest extends Abstract_IntegTest { @SneakyThrows @Test @UseReporter(DiffReporter.class) - public void can_create_staff_member() { + public void createStaffMemberWithPhoto2() { // given final var staffName = "Fred Smith"; @@ -67,27 +68,33 @@ public class Staff_Orig_IntegTest extends Abstract_IntegTest { return bookmarkService.bookmarkFor(staffMember); }).valueAsNonNullElseFail(); + assertThat(bookmarkBeforeIfAny).isEmpty(); + + // and given final var departmentName = "Classics"; final var departmentBookmark = transactionService.callTransactional(Propagation.REQUIRED, () -> { final var staffMember = departmentRepository.findByName(departmentName); return bookmarkService.bookmarkFor(staffMember).orElseThrow(); }).valueAsNonNullElseFail(); - assertThat(bookmarkBeforeIfAny).isEmpty(); - - final var photoEncoded = readFileAndEncodeAsBlob("StaffMember-photo-Bar.pdf"); String departmentHref = asRelativeHref(departmentBookmark); Invocation.Builder departmentRequest = restfulClient.request(departmentHref); Response departmentResponse = departmentRequest.get(); assertThat(departmentResponse.getStatusInfo().getFamily()).isEqualTo(Response.Status.Family.SUCCESSFUL); - final var requestBuilder = restfulClient.request("services/university.dept.Staff/actions/createStaffMemberWithPhoto/invoke"); + // and given + final var photoEncoded = readFileAndEncodeAsBlob("StaffMember-photo-Bar.pdf"); + // when create request + final var requestBuilder = restfulClient.request("services/university.dept.Staff/actions/createStaffMemberWithPhoto2/invoke"); final var body = new Body(staffName, asAbsoluteHref(departmentBookmark), photoEncoded); final var bodyJson = gsonBuilder.create().toJson(body); - // when + // then + Approvals.verify(bodyJson, jsonOptions()); + + // and when send request val response = requestBuilder.post(Entity.entity(bodyJson, "application/json")); // then @@ -96,7 +103,6 @@ public class Staff_Orig_IntegTest extends Abstract_IntegTest { assertThat(response.getStatus()).isEqualTo(Response.Status.OK.getStatusCode()); // and also json response - // Approvals.verify(entity, jsonOptions()); // and also object is created in database final var bookmarkAfterIfAny = transactionService.callTransactional(Propagation.REQUIRED, () -> { @@ -106,14 +112,14 @@ public class Staff_Orig_IntegTest extends Abstract_IntegTest { assertThat(bookmarkAfterIfAny).isNotEmpty(); } - private String asRelativeHref(Bookmark bookmark) { - return String.format("objects/%s/%s", bookmark.getLogicalTypeName(), bookmark.getIdentifier()); - } - private String asAbsoluteHref(Bookmark bookmark) { return String.format("%s%s", restfulClient.getConfig().getRestfulBaseUrl(), asRelativeHref(bookmark)); } + private String asRelativeHref(Bookmark bookmark) { + return String.format("objects/%s/%s", bookmark.getLogicalTypeName(), bookmark.getIdentifier()); + } + private String readFileAndEncodeAsBlob(String fileName) throws IOException, URISyntaxException { byte[] bytes = Resources.toByteArray(Resources.getResource(Abstract_IntegTest.class, fileName)); String photoEncoded = encodePdf(fileName, bytes); @@ -135,16 +141,14 @@ public class Staff_Orig_IntegTest extends Abstract_IntegTest { * @param blobValue - is the Blob encoded format: "filename.pdf:application/pdf:pdfBytesBase64Encoded" */ Body(String nameValue, String departmentHrefValue, String blobValue) { - photo = new org.apache.causeway.viewer.restfulobjects.test.scenarios.staff.Body.Blob(blobValue); - name = new org.apache.causeway.viewer.restfulobjects.test.scenarios.staff.Body.Name(nameValue); - department = new org.apache.causeway.viewer.restfulobjects.test.scenarios.staff.Body.Department(new org.apache.causeway.viewer.restfulobjects.test.scenarios.staff.Body.Value(departmentHrefValue)); + photo = new Blob(blobValue); + name = new Name(nameValue); + department = new Department(new Department.Value(departmentHrefValue)); } - private org.apache.causeway.viewer.restfulobjects.test.scenarios.staff.Body.Name name; - - private org.apache.causeway.viewer.restfulobjects.test.scenarios.staff.Body.Department department; - - private org.apache.causeway.viewer.restfulobjects.test.scenarios.staff.Body.Blob photo; + private Name name; + private Department department; + private Blob photo; @lombok.Value static class Name { @@ -153,22 +157,21 @@ public class Staff_Orig_IntegTest extends Abstract_IntegTest { @lombok.Value static class Department { - private org.apache.causeway.viewer.restfulobjects.test.scenarios.staff.Body.Value value; - } + private Value value; + + @lombok.Value + static class Value { + private String href; + } - @lombok.Value - static class Value { - private String href; } @lombok.Value static class Blob { private String value; } - } - } diff --git a/viewers/restfulobjects/test/src/test/java/org/apache/causeway/viewer/restfulobjects/test/scenarios/staff/Staff_lowlevel_v2_IntegTest.createStaffMemberWithPhoto2.approved.json b/viewers/restfulobjects/test/src/test/java/org/apache/causeway/viewer/restfulobjects/test/scenarios/staff/Staff_lowlevel_v2_IntegTest.createStaffMemberWithPhoto2.approved.json new file mode 100644 index 0000000000..a6123f9fb9 --- /dev/null +++ b/viewers/restfulobjects/test/src/test/java/org/apache/causeway/viewer/restfulobjects/test/scenarios/staff/Staff_lowlevel_v2_IntegTest.createStaffMemberWithPhoto2.approved.json @@ -0,0 +1,17 @@ +{ + "name" : { + "value" : "Fred Smith" + }, + "department" : { + "value" : { + "href" : "http://0.0.0.0:NNN/restful/objects/university.dept.Department/NNN" + } + }, + "photo" : { + "value" : { + "name" : "StaffMember-photo-Bar.pdf", + "mimeType" : "application/pdf", + "bytes" : "JVBERi0xLjcNCiW1tbW1DQoxIDAgb2JqDQo8PC9UeXBlL0NhdGFsb2cvUGFnZXMgMiAwIFIvTGFuZyhlbi1HQikgL1N0cnVjdFRyZWVSb290IDEyIDAgUi9NYXJrSW5mbzw8L01hcmtlZCB0cnVlPj4vTWV0YWRhdGEgMzIgMCBSL1ZpZXdlclByZWZlcmVuY2VzIDMzIDAgUj4+DQplbmRvYmoNCjIgMCBvYmoNCjw8L1R5cGUvUGFnZXMvQ291bnQgMS9LaWRzWyAzIDAgUl0gPj4NCmVuZG9iag0KMyAwIG9iag0KPDwvVHlwZS9QYWdlL1BhcmVudCAyIDAgUi9SZXNvdXJjZXM8PC9Gb250PDwvRjEgNSAwIFIvRjIgOSAwIFI+Pi9FeHRHU3RhdGU8PC9HUzcgNyAwIFIvR1M4IDggMCBSPj4vUHJvY1NldFsvUERGL1RleHQvSW1hZ2VCL0l [...] + } + } +} \ No newline at end of file diff --git a/viewers/restfulobjects/test/src/test/java/org/apache/causeway/viewer/restfulobjects/test/scenarios/staff/Staff_Orig_IntegTest.java b/viewers/restfulobjects/test/src/test/java/org/apache/causeway/viewer/restfulobjects/test/scenarios/staff/Staff_lowlevel_v2_IntegTest.java similarity index 70% rename from viewers/restfulobjects/test/src/test/java/org/apache/causeway/viewer/restfulobjects/test/scenarios/staff/Staff_Orig_IntegTest.java rename to viewers/restfulobjects/test/src/test/java/org/apache/causeway/viewer/restfulobjects/test/scenarios/staff/Staff_lowlevel_v2_IntegTest.java index cafae75234..26b6eeb8a1 100644 --- a/viewers/restfulobjects/test/src/test/java/org/apache/causeway/viewer/restfulobjects/test/scenarios/staff/Staff_Orig_IntegTest.java +++ b/viewers/restfulobjects/test/src/test/java/org/apache/causeway/viewer/restfulobjects/test/scenarios/staff/Staff_lowlevel_v2_IntegTest.java @@ -19,7 +19,6 @@ package org.apache.causeway.viewer.restfulobjects.test.scenarios.staff; import java.io.IOException; -import java.net.URISyntaxException; import java.util.Base64; import javax.ws.rs.client.Entity; @@ -29,6 +28,9 @@ import javax.ws.rs.core.Response; import com.google.common.io.Resources; import com.google.gson.GsonBuilder; +import org.apache.causeway.applib.value.Blob; + +import org.approvaltests.Approvals; import org.approvaltests.reporters.DiffReporter; import org.approvaltests.reporters.UseReporter; import org.junit.jupiter.api.BeforeEach; @@ -45,7 +47,7 @@ import lombok.Getter; import lombok.SneakyThrows; import lombok.val; -public class Staff_Orig_IntegTest extends Abstract_IntegTest { +public class Staff_lowlevel_v2_IntegTest extends Abstract_IntegTest { private GsonBuilder gsonBuilder; @@ -57,7 +59,7 @@ public class Staff_Orig_IntegTest extends Abstract_IntegTest { @SneakyThrows @Test @UseReporter(DiffReporter.class) - public void can_create_staff_member() { + public void createStaffMemberWithPhoto2() { // given final var staffName = "Fred Smith"; @@ -67,27 +69,33 @@ public class Staff_Orig_IntegTest extends Abstract_IntegTest { return bookmarkService.bookmarkFor(staffMember); }).valueAsNonNullElseFail(); + assertThat(bookmarkBeforeIfAny).isEmpty(); + + // and given final var departmentName = "Classics"; final var departmentBookmark = transactionService.callTransactional(Propagation.REQUIRED, () -> { final var staffMember = departmentRepository.findByName(departmentName); return bookmarkService.bookmarkFor(staffMember).orElseThrow(); }).valueAsNonNullElseFail(); - assertThat(bookmarkBeforeIfAny).isEmpty(); - - final var photoEncoded = readFileAndEncodeAsBlob("StaffMember-photo-Bar.pdf"); String departmentHref = asRelativeHref(departmentBookmark); Invocation.Builder departmentRequest = restfulClient.request(departmentHref); Response departmentResponse = departmentRequest.get(); assertThat(departmentResponse.getStatusInfo().getFamily()).isEqualTo(Response.Status.Family.SUCCESSFUL); - final var requestBuilder = restfulClient.request("services/university.dept.Staff/actions/createStaffMemberWithPhoto/invoke"); + // and given + final var photoEncoded = readFileAsBlob("StaffMember-photo-Bar.pdf"); + // when create request + final var requestBuilder = restfulClient.request("services/university.dept.Staff/actions/createStaffMemberWithPhoto2/invoke"); final var body = new Body(staffName, asAbsoluteHref(departmentBookmark), photoEncoded); final var bodyJson = gsonBuilder.create().toJson(body); - // when + // then + Approvals.verify(bodyJson, jsonOptions()); + + // and when send request val response = requestBuilder.post(Entity.entity(bodyJson, "application/json")); // then @@ -96,7 +104,6 @@ public class Staff_Orig_IntegTest extends Abstract_IntegTest { assertThat(response.getStatus()).isEqualTo(Response.Status.OK.getStatusCode()); // and also json response - // Approvals.verify(entity, jsonOptions()); // and also object is created in database final var bookmarkAfterIfAny = transactionService.callTransactional(Propagation.REQUIRED, () -> { @@ -106,45 +113,37 @@ public class Staff_Orig_IntegTest extends Abstract_IntegTest { assertThat(bookmarkAfterIfAny).isNotEmpty(); } - private String asRelativeHref(Bookmark bookmark) { - return String.format("objects/%s/%s", bookmark.getLogicalTypeName(), bookmark.getIdentifier()); - } - private String asAbsoluteHref(Bookmark bookmark) { return String.format("%s%s", restfulClient.getConfig().getRestfulBaseUrl(), asRelativeHref(bookmark)); } - private String readFileAndEncodeAsBlob(String fileName) throws IOException, URISyntaxException { - byte[] bytes = Resources.toByteArray(Resources.getResource(Abstract_IntegTest.class, fileName)); - String photoEncoded = encodePdf(fileName, bytes); - return photoEncoded; + private String asRelativeHref(Bookmark bookmark) { + return String.format("objects/%s/%s", bookmark.getLogicalTypeName(), bookmark.getIdentifier()); } - private String encodePdf(final String fileName, final byte[] pdfBytes) throws URISyntaxException { - final String pdfBytesEncoded = Base64.getEncoder().encodeToString(pdfBytes); - final String encodedBlob = String.format("%s:%s:%s", fileName, "application/pdf", pdfBytesEncoded); - return encodedBlob; + private Blob readFileAsBlob(String fileName) throws IOException { + byte[] bytes = Resources.toByteArray(Resources.getResource(Abstract_IntegTest.class, fileName)); + return new Blob(fileName, "application/pdf", bytes); } + @Getter static class Body { /** * @param nameValue * @param departmentHrefValue - * @param blobValue - is the Blob encoded format: "filename.pdf:application/pdf:pdfBytesBase64Encoded" + * @param blob - is the Blob to be formatted */ - Body(String nameValue, String departmentHrefValue, String blobValue) { - photo = new org.apache.causeway.viewer.restfulobjects.test.scenarios.staff.Body.Blob(blobValue); - name = new org.apache.causeway.viewer.restfulobjects.test.scenarios.staff.Body.Name(nameValue); - department = new org.apache.causeway.viewer.restfulobjects.test.scenarios.staff.Body.Department(new org.apache.causeway.viewer.restfulobjects.test.scenarios.staff.Body.Value(departmentHrefValue)); + Body(String nameValue, String departmentHrefValue, org.apache.causeway.applib.value.Blob blob) { + name = new Name(nameValue); + department = new Department(new Department.Value(departmentHrefValue)); + photo = new Blob(new Blob.Value(blob.getName(), blob.getMimeType().toString(), Base64.getEncoder().encodeToString(blob.getBytes()))); } - private org.apache.causeway.viewer.restfulobjects.test.scenarios.staff.Body.Name name; - - private org.apache.causeway.viewer.restfulobjects.test.scenarios.staff.Body.Department department; - - private org.apache.causeway.viewer.restfulobjects.test.scenarios.staff.Body.Blob photo; + private Name name; + private Department department; + private Blob photo; @lombok.Value static class Name { @@ -153,22 +152,30 @@ public class Staff_Orig_IntegTest extends Abstract_IntegTest { @lombok.Value static class Department { - private org.apache.causeway.viewer.restfulobjects.test.scenarios.staff.Body.Value value; - } + private Value value; + + @lombok.Value + static class Value { + private String href; + } - @lombok.Value - static class Value { - private String href; } + @lombok.Value static class Blob { - private String value; + private Value value; + + @lombok.Value + static class Value { + private String name; + private String mimeType; + private String bytes; + } } } - }
