From bd9c79a39d4a62824a3d7e3b22072ee031cd3d0e Mon Sep 17 00:00:00 2001 From: Michael Hoennig Date: Fri, 1 Nov 2024 16:32:51 +0100 Subject: [PATCH] now use ??? and allow infix notiation for two optional values --- .../hs/office/scenarios/ScenarioTest.java | 1 - .../hs/office/scenarios/TemplateResolver.java | 49 +++++++++++-------- .../hs/office/scenarios/TestReport.java | 4 +- .../scenarios/partner/CreatePartner.java | 12 ++--- 4 files changed, 37 insertions(+), 29 deletions(-) diff --git a/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/ScenarioTest.java b/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/ScenarioTest.java index acf31795..4600584a 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/ScenarioTest.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/ScenarioTest.java @@ -69,7 +69,6 @@ public abstract class ScenarioTest extends ContextBasedTest { @AfterEach void cleanup() { // final TestInfo testInfo properties.clear(); - // FIXME: Delete all aliases as well to force HTTP GET queries in each scenario? testReport.close(); } diff --git a/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/TemplateResolver.java b/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/TemplateResolver.java index 13e01324..494f785f 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/TemplateResolver.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/TemplateResolver.java @@ -1,5 +1,7 @@ package net.hostsharing.hsadminng.hs.office.scenarios; +import org.apache.commons.lang3.StringUtils; + import java.net.URLEncoder; import java.nio.charset.StandardCharsets; import java.util.Arrays; @@ -8,13 +10,15 @@ import java.util.regex.Pattern; import java.util.stream.Collectors; public class TemplateResolver { - private final static Pattern pattern = Pattern.compile(",\\s*([}\\]])", Pattern.MULTILINE); + + private final static Pattern pattern = Pattern.compile(",(\\s*})", Pattern.MULTILINE); + private static final String IF_NOT_FOUND_SYMBOL = "???"; enum PlaceholderPrefix { RAW('%') { @Override String convert(final Object value) { - return value.toString(); + return value != null ? value.toString() : ""; } }, JSON_QUOTED('$'){ @@ -26,7 +30,7 @@ public class TemplateResolver { URI_ENCODED('&'){ @Override String convert(final Object value) { - return URLEncoder.encode(value.toString(), StandardCharsets.UTF_8); + return value != null ? URLEncoder.encode(value.toString(), StandardCharsets.UTF_8) : ""; } }; @@ -59,21 +63,26 @@ public class TemplateResolver { String resolve() { final var resolved = copy(); - final var withoutDroppedLines = removeDroppedLinkes(resolved); - final var result = removeSpareCommas(withoutDroppedLines); + final var withoutDroppedLines = dropLinesWithNullProperties(resolved); + final var result = removeDanglingCommas(withoutDroppedLines); return result; } - private static String removeSpareCommas(final String withoutDroppedLines) { + private static String removeDanglingCommas(final String withoutDroppedLines) { return pattern.matcher(withoutDroppedLines).replaceAll("$1"); } - private String removeDroppedLinkes(final String text) { + private String dropLinesWithNullProperties(final String text) { return Arrays.stream(text.split("\n")) - .filter(line -> !line.contains("<<>")) + .filter(TemplateResolver::keepLine) .collect(Collectors.joining("\n")); } + private static boolean keepLine(final String line) { + final var trimmed = line.trim(); + return !trimmed.endsWith("null,") && !trimmed.endsWith("null"); + } + private String copy() { while (hasMoreChars()) { if (PlaceholderPrefix.contains(currentChar()) && nextChar() == '{') { @@ -113,23 +122,21 @@ public class TemplateResolver { } private Object propVal(final String name) { - if (name.endsWith("??")) { - final String pureName = name.substring(0, name.length() - "??".length()); - final var val = properties.get(pureName); + if (name.endsWith(IF_NOT_FOUND_SYMBOL)) { + final String pureName = name.substring(0, name.length() - IF_NOT_FOUND_SYMBOL.length()); + return properties.get(pureName); + } else if (name.contains(IF_NOT_FOUND_SYMBOL)) { + final var parts = StringUtils.split(name, IF_NOT_FOUND_SYMBOL); + final var head = properties.get(parts[0]); + final var tail = properties.get(parts[1]); + return head != null ? head : tail; // FIXME: What if tail is null as well? + } else { + final var val = properties.get(name); if (val == null) { - return "<<>"; + throw new IllegalStateException("Missing required property: " + name); } return val; } - if (name.endsWith("?")) { - final String pureName = name.substring(0, name.length() - "?".length()); - return properties.get(pureName); - } - final var val = properties.get(name); - if (val == null) { - throw new IllegalStateException("Missing required property: " + name); - } - return val; } private void skipChar(final char expectedChar) { diff --git a/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/TestReport.java b/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/TestReport.java index 02123a14..8aba4319 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/TestReport.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/TestReport.java @@ -57,7 +57,9 @@ public class TestReport { } public void close() { - markdownReport.close(); + if (markdownReport != null) { + markdownReport.close(); + } } private static Object orderNumber(final Method method) { diff --git a/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/partner/CreatePartner.java b/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/partner/CreatePartner.java index 0aa485ad..1b408c9c 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/partner/CreatePartner.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/partner/CreatePartner.java @@ -28,13 +28,13 @@ public class CreatePartner extends UseCase { "Even in production data we expect this query to return just a single result." // TODO.impl: add constraint? ); - obtain("Partner-Person", () -> + obtain("Person: %{tradeName???%{givenName???} %{familyName???}}", () -> httpPost("/api/hs/office/persons", usingJsonBody(""" { - "personType": ${personType}, - "tradeName": ${tradeName??}, - "givenName": ${givenName??}, - "familyName": ${familyName??} + "personType": ${personType???}, + "tradeName": ${tradeName???}, + "givenName": ${givenName???}, + "familyName": ${familyName???} } """)) .expecting(HttpStatus.CREATED).expecting(ContentType.JSON) @@ -57,7 +57,7 @@ public class CreatePartner extends UseCase { "partnerNumber": ${partnerNumber}, "partnerRel": { "anchorUuid": ${Person: Hostsharing eG}, - "holderUuid": ${Partner-Person}, + "holderUuid": ${Person: %{tradeName???%{givenName???} %{familyName???}}}, "contactUuid": ${Contact: %{contactCaption}} }, "details": {