diff --git a/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/HsOfficeScenarioTests.java b/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/HsOfficeScenarioTests.java index 0b95bdaf..4d785a63 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/HsOfficeScenarioTests.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/HsOfficeScenarioTests.java @@ -444,7 +444,7 @@ class HsOfficeScenarioTests extends ScenarioTest { @Test @Order(4301) @Requires("Membership: M-3101000 - Test AG") - @Produces("Coop-Assets M-3101000 - Test AG - DEPOSIT Transaction") + @Produces("Coop-Assets: M-3101000 - Test AG - DEPOSIT Transaction") void shouldSubscribeCoopAssets() { new CreateCoopAssetsDepositTransaction(scenarioTest) .given("memberNumber", "M-3101000") @@ -468,8 +468,8 @@ class HsOfficeScenarioTests extends ScenarioTest { @Test @Order(4303) - @Requires("Coop-Assets M-3101000 - Test AG - DEPOSIT Transaction") - @Produces("Coop-Assets M-3101000 - Test AG - DISBURSAL Transaction") + @Requires("Coop-Assets: M-3101000 - Test AG - DEPOSIT Transaction") + @Produces("Coop-Assets: M-3101000 - Test AG - DISBURSAL Transaction") void shouldDisburseCoopAssets() { new CreateCoopAssetsDisbursalTransaction(scenarioTest) .given("memberNumber", "M-3101000") @@ -482,8 +482,8 @@ class HsOfficeScenarioTests extends ScenarioTest { @Test @Order(4304) - @Requires("Coop-Assets M-3101000 - Test AG - DEPOSIT Transaction") - @Produces(explicitly = "Coop-Assets M-3101000 - Test AG - TRANSFER Transaction", implicitly = "Membership M-4303000 - New AG") + @Requires("Coop-Assets: M-3101000 - Test AG - DEPOSIT Transaction") + @Produces(explicitly = "Coop-Assets: M-3101000 - Test AG - TRANSFER Transaction", implicitly = "Membership: M-4303000 - New AG") void shouldTransferCoopAssets() { new CreateCoopAssetsTransferTransaction(scenarioTest) .given("transferringMemberNumber", "M-3101000") @@ -497,7 +497,7 @@ class HsOfficeScenarioTests extends ScenarioTest { @Test @Order(4305) - @Requires("Coop-Assets M-3101000 - Test AG - TRANSFER Transaction") + @Requires("Coop-Assets: M-3101000 - Test AG - TRANSFER Transaction") void shouldRevertCoopAssetsTransferIncludingRelatedAssetAdoption() { new CreateCoopAssetsRevertTransferTransaction(scenarioTest) .given("transferringMemberNumber", "M-3101000") diff --git a/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/membership/coopassets/CreateCoopAssetsTransferTransaction.java b/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/membership/coopassets/CreateCoopAssetsTransferTransaction.java index faf3779d..8a9a31da 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/membership/coopassets/CreateCoopAssetsTransferTransaction.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/office/scenarios/membership/coopassets/CreateCoopAssetsTransferTransaction.java @@ -19,7 +19,7 @@ public class CreateCoopAssetsTransferTransaction extends CreateCoopAssetsTransac .given("emailAddress", "board-of-directors@new-ag.example.org") ); - requires("Membership: New AG", alias -> new CreateMembership(testSuite) + requires("Membership: %{adoptingMemberNumber} - New AG", alias -> new CreateMembership(testSuite) .given("memberNumber", toPartnerNumber("%{adoptingMemberNumber}")) .given("partnerName", "New AG") .given("validFrom", "2024-11-15") diff --git a/src/test/java/net/hostsharing/hsadminng/test/scenarios/Produces.java b/src/test/java/net/hostsharing/hsadminng/test/scenarios/Produces.java index 9acdd3ab..7ad5bb9c 100644 --- a/src/test/java/net/hostsharing/hsadminng/test/scenarios/Produces.java +++ b/src/test/java/net/hostsharing/hsadminng/test/scenarios/Produces.java @@ -1,10 +1,15 @@ package net.hostsharing.hsadminng.test.scenarios; +import lombok.experimental.UtilityClass; + import java.lang.annotation.Retention; import java.lang.annotation.Target; +import java.util.HashSet; +import java.util.Set; import static java.lang.annotation.ElementType.METHOD; import static java.lang.annotation.RetentionPolicy.RUNTIME; +import static java.util.Arrays.asList; @Target(METHOD) @Retention(RUNTIME) @@ -13,4 +18,29 @@ public @interface Produces { String explicitly() default ""; // same as value String[] implicitly() default {}; boolean permanent() default true; // false means that the object gets deleted again in the process + + @UtilityClass + final class Aggregator { + + public static Set producedAliases(final Produces producesAnnot) { + return allOf( + producesAnnot.value(), + producesAnnot.explicitly(), + producesAnnot.implicitly()); + } + + + + private Set allOf(final String value, final String explicitly, final String[] implicitly) { + final var all = new HashSet(); + if (!value.isEmpty()) { + all.add(value); + } + if (!explicitly.isEmpty()) { + all.add(explicitly); + } + all.addAll(asList(implicitly)); + return all; + } + } } diff --git a/src/test/java/net/hostsharing/hsadminng/test/scenarios/ScenarioTest.java b/src/test/java/net/hostsharing/hsadminng/test/scenarios/ScenarioTest.java index e23fc584..3364554f 100644 --- a/src/test/java/net/hostsharing/hsadminng/test/scenarios/ScenarioTest.java +++ b/src/test/java/net/hostsharing/hsadminng/test/scenarios/ScenarioTest.java @@ -15,24 +15,22 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.TestInfo; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.web.server.LocalServerPort; -import org.testcontainers.shaded.org.apache.commons.lang3.ObjectUtils; import java.lang.reflect.Method; import java.math.BigDecimal; import java.util.HashMap; -import java.util.HashSet; import java.util.LinkedHashMap; import java.util.Map; +import java.util.Objects; import java.util.Optional; -import java.util.Set; import java.util.Stack; import java.util.UUID; import java.util.stream.Collectors; import java.util.stream.Stream; -import static java.util.Arrays.asList; import static java.util.Arrays.stream; import static java.util.Optional.ofNullable; +import static net.hostsharing.hsadminng.test.scenarios.Produces.Aggregator.producedAliases; import static net.hostsharing.hsadminng.test.scenarios.TemplateResolver.Resolver.DROP_COMMENTS; import static org.apache.commons.lang3.StringUtils.isNotBlank; import static org.assertj.core.api.Assertions.assertThat; @@ -56,7 +54,7 @@ public abstract class ScenarioTest extends ContextBasedTest { @Override public String toString() { - return ObjectUtils.toString(uuid); + return Objects.toString(uuid); } } @@ -77,7 +75,7 @@ public abstract class ScenarioTest extends ContextBasedTest { @SneakyThrows @BeforeEach - void init(final TestInfo testInfo) { + void beforeScenario(final TestInfo testInfo) { createHostsharingPerson(); try { testInfo.getTestMethod().ifPresent(currentTestMethod -> { @@ -91,7 +89,20 @@ public abstract class ScenarioTest extends ContextBasedTest { } @AfterEach - void cleanup() { // final TestInfo testInfo + void afterScenario(final TestInfo testInfo) { // final TestInfo testInfo + testInfo.getTestMethod() .ifPresent(currentTestMethod -> { + // FIXME: extract to method + final var producesAnnot = currentTestMethod.getAnnotation(Produces.class); + if (producesAnnot != null && producesAnnot.permanent()) { + final var testMethodProduces = producedAliases(producesAnnot); + testMethodProduces.forEach(declaredAlias -> + assertThat(knowVariables().containsKey(declaredAlias)) + .as("@Producer method " + currentTestMethod.getName() + + " did declare but not produce \"" + declaredAlias + "\"") + .isTrue() ); + } + }); + properties.clear(); testReport.close(); } @@ -122,10 +133,7 @@ public abstract class ScenarioTest extends ContextBasedTest { if (testMethodRequires != null) { for (Method potentialProducerMethod : getPotentialProducerMethods()) { final var producesAnnot = potentialProducerMethod.getAnnotation(Produces.class); - final var testMethodProduces = allOf( - producesAnnot.value(), - producesAnnot.explicitly(), - producesAnnot.implicitly()); + final var testMethodProduces = producedAliases(producesAnnot); // @formatter:off if ( // that method can produce something required testMethodProduces.contains(testMethodRequires) && @@ -141,10 +149,6 @@ public abstract class ScenarioTest extends ContextBasedTest { // and finally we call the producer method invokeProducerMethod(this, potentialProducerMethod); - - assertThat(knowVariables().containsKey(testMethodRequires)) - .as("@Producer method " + potentialProducerMethod.getName() + " did declare but not produce \"" + testMethodRequires + "\"") - .isTrue(); } // @formatter:on } @@ -157,7 +161,7 @@ public abstract class ScenarioTest extends ContextBasedTest { private void keepProducesAlias(final Method currentTestMethod) { final var producesAnnot = currentTestMethod.getAnnotation(Produces.class); - if ( producesAnnot != null ) { + if (producesAnnot != null) { final var producesAlias = isNotBlank(producesAnnot.value()) ? producesAnnot.value() : producesAnnot.explicitly(); assertThat(producesAlias) .as(currentTestMethod.getName() + " must define either value or explicit for @Produces") @@ -191,18 +195,6 @@ public abstract class ScenarioTest extends ContextBasedTest { } } - private Set allOf(final String value, final String explicitly, final String[] implicitly) { - final var all = new HashSet(); - if (!value.isEmpty()) { - all.add(value); - } - if (!explicitly.isEmpty()) { - all.add(explicitly); - } - all.addAll(asList(implicitly)); - return all; - } - static boolean containsAlias(final String alias) { return aliases.containsKey(alias); } diff --git a/src/test/java/net/hostsharing/hsadminng/test/scenarios/UseCase.java b/src/test/java/net/hostsharing/hsadminng/test/scenarios/UseCase.java index 1209cfbc..283058e7 100644 --- a/src/test/java/net/hostsharing/hsadminng/test/scenarios/UseCase.java +++ b/src/test/java/net/hostsharing/hsadminng/test/scenarios/UseCase.java @@ -71,9 +71,7 @@ public abstract class UseCase> { } public final void requires(final String alias, final Function> useCaseFactory) { - if (!ScenarioTest.containsAlias(alias)) { - requirements.put(alias, useCaseFactory); - } + requirements.put(alias, useCaseFactory); } public final HttpResponse doRun() { @@ -89,8 +87,9 @@ public abstract class UseCase> { testReport.printLine(""); testReport.silent(() -> requirements.forEach((alias, factory) -> { - if (!ScenarioTest.containsAlias(alias)) { - factory.apply(alias).run().keepAs(alias); + final var resolvedAlias = ScenarioTest.resolve(alias, DROP_COMMENTS); + if (!ScenarioTest.containsAlias(resolvedAlias)) { + factory.apply(resolvedAlias).run().keepAs(resolvedAlias); } }) );