Compare commits

..

No commits in common. "876b3c526e1500bce2f038df9f6234badffe3bd7" and "36b0eb08b491618dae51d61febdb8b49106d8b94" have entirely different histories.

9 changed files with 36 additions and 69 deletions

View File

@ -25,14 +25,14 @@ class HsOfficeUseCasesTest extends UseCaseTest {
@Test @Test
@Order(1010) @Order(1010)
@Produces(explicitly = "Partner: Test AG", implicitly = "Person: Test AG") @Produces("Partner: Test AG")
void shouldCreatePartner() { void shouldCreatePartner() {
new CreatePartner(this, "Partner: Test AG") new CreatePartner(this, "Partner: Test AG")
.given("partnerNumber", 31010) .given("partnerNumber", 30001)
.given("personType", "LEGAL_PERSON") .given("personType", "LEGAL_PERSON")
.given("tradeName", "Test AG") .given("tradeName", "Test AG")
.given("contactCaption", "Test AG - Board of Directors") .given("contactCaption", "Test AG - Bord of Directors")
.given("emailAddress", "board-of-directors@test-ag.example.org") .given("emailAddress", "bord-of-directors@test-ag.example.org")
.doRun() .doRun()
.keep(); .keep();
} }
@ -66,7 +66,7 @@ class HsOfficeUseCasesTest extends UseCaseTest {
@Test @Test
@Order(2011) @Order(2011)
@Requires("Person: Test AG") @Requires("Partner: Test AG") // FIXME: eigentlich "Person: Test AG"
@Produces("Debitor: Billing GmbH") @Produces("Debitor: Billing GmbH")
void shouldCreateExternalDebitorForPartner() { void shouldCreateExternalDebitorForPartner() {
new CreateExternalDebitorForPartner(this, "Debitor: Billing GmbH") new CreateExternalDebitorForPartner(this, "Debitor: Billing GmbH")
@ -86,7 +86,7 @@ class HsOfficeUseCasesTest extends UseCaseTest {
@Test @Test
@Order(2020) @Order(2020)
@Requires("Person: Test AG") @Requires("Partner: Test AG") // FIXME: eigentlich "Person: Test AG"
void shouldDeleteDebitor() { void shouldDeleteDebitor() {
new DeleteDebitor(this) new DeleteDebitor(this)
.given("partnerNumber", 31020) .given("partnerNumber", 31020)
@ -96,13 +96,8 @@ class HsOfficeUseCasesTest extends UseCaseTest {
@Test @Test
@Order(3000) @Order(3000)
@Requires("Partner: Test AG") @Requires("Partner: Test AG") // FIXME: eigentlich "Person: Test AG"
void shouldCreateMembershipForPartner() { void shouldCreateMembershipForPartner() {
new CreateMembership(this) new CreateMembership(this).doRun();
.given("partnerName", "Test AG")
.given("memberNumberSuffix", "00")
.given("validFrom", "2024-10-15")
.given("membershipFeeBillable", "true")
.doRun();
} }
} }

View File

@ -4,12 +4,11 @@ import java.lang.annotation.Retention;
import java.lang.annotation.Target; import java.lang.annotation.Target;
import static java.lang.annotation.ElementType.METHOD; import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.RetentionPolicy.CLASS;
import static java.lang.annotation.RetentionPolicy.RUNTIME; import static java.lang.annotation.RetentionPolicy.RUNTIME;
@Target(METHOD) @Target(METHOD)
@Retention(RUNTIME) @Retention(RUNTIME)
public @interface Produces { public @interface Produces {
String value() default ""; // same as explicitly, makes it possible to omit the property name String value();
String explicitly() default ""; // same as value
String[] implicitly() default {};
} }

View File

@ -14,6 +14,7 @@ import java.util.UUID;
import java.util.function.Function; import java.util.function.Function;
import java.util.function.Supplier; import java.util.function.Supplier;
import static org.assertj.core.api.Assumptions.assumeThat;
import static org.hamcrest.Matchers.startsWith; import static org.hamcrest.Matchers.startsWith;
public abstract class UseCase<T extends UseCase<?>> { public abstract class UseCase<T extends UseCase<?>> {
@ -43,6 +44,13 @@ public abstract class UseCase<T extends UseCase<?>> {
} }
} }
public void requires(final String alias) {
assumeThat(UseCaseTest.containsAlias(alias))
.as("skipping because alias '" + alias + "' not found, @Produces(...) missing?")
.isTrue();
log("depends on [" + alias + "](" + UseCaseTest.getAlias(alias).useCase().getSimpleName() + ".md)");
}
public final HttpResponse doRun() { public final HttpResponse doRun() {
log("### Given Properties\n"); log("### Given Properties\n");
log(""" log("""

View File

@ -7,8 +7,6 @@ import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonRepository;
import net.hostsharing.hsadminng.lambda.Reducer; import net.hostsharing.hsadminng.lambda.Reducer;
import net.hostsharing.hsadminng.rbac.context.ContextBasedTest; import net.hostsharing.hsadminng.rbac.context.ContextBasedTest;
import net.hostsharing.hsadminng.rbac.test.JpaAttempt; import net.hostsharing.hsadminng.rbac.test.JpaAttempt;
import org.apache.commons.collections4.SetUtils;
import org.hibernate.AssertionFailure;
import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Order; import org.junit.jupiter.api.Order;
@ -22,14 +20,12 @@ import java.io.PrintWriter;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.Map; import java.util.Map;
import java.util.Set;
import java.util.UUID; import java.util.UUID;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import static java.util.Arrays.asList; import static java.util.Arrays.stream;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
public abstract class UseCaseTest extends ContextBasedTest { public abstract class UseCaseTest extends ContextBasedTest {
@ -60,7 +56,7 @@ public abstract class UseCaseTest extends ContextBasedTest {
@BeforeEach @BeforeEach
void init(final TestInfo testInfo) { void init(final TestInfo testInfo) {
createHostsharingPerson(); createHostsharingPerson();
callRequiredProducers(testInfo); callPrerequisites(testInfo);
createTestLogMarkdownFile(testInfo); createTestLogMarkdownFile(testInfo);
} }
@ -102,7 +98,7 @@ public abstract class UseCaseTest extends ContextBasedTest {
log("## Testcase " + testMethodName.replaceAll("([a-z])([A-Z]+)", "$1 $2")); log("## Testcase " + testMethodName.replaceAll("([a-z])([A-Z]+)", "$1 $2"));
} }
private void callRequiredProducers(final TestInfo testInfo) throws IllegalAccessException, InvocationTargetException { private void callPrerequisites(final TestInfo testInfo) throws IllegalAccessException, InvocationTargetException {
final var testMethodRequired = testInfo.getTestMethod() final var testMethodRequired = testInfo.getTestMethod()
.map(m -> m.getAnnotation(Requires.class)) .map(m -> m.getAnnotation(Requires.class))
.map(Requires::value) .map(Requires::value)
@ -111,48 +107,12 @@ public abstract class UseCaseTest extends ContextBasedTest {
for (Method testMethod : getClass().getDeclaredMethods()) { for (Method testMethod : getClass().getDeclaredMethods()) {
final var producesAnnot = testMethod.getAnnotation(Produces.class); final var producesAnnot = testMethod.getAnnotation(Produces.class);
if (producesAnnot != null) { if (producesAnnot != null) {
final var testMethodProduces = allOf(producesAnnot.value(), producesAnnot.explicitly(), producesAnnot.implicitly()); final var testMethodProduct = producesAnnot.value();
if ( // that method can produce something required if (testMethodProduct.equals(testMethodRequired))
testMethodProduces.contains(testMethodRequired) &&
// and it does not produce anything we already have (would cause errors)
SetUtils.intersection(testMethodProduces, knowVariables().keySet()).isEmpty())
// then we call the producer method
testMethod.invoke(this); testMethod.invoke(this);
} }
} }
} }
// public void requires(final String alias) {
// assumeThat(UseCaseTest.containsAlias(alias))
// .as("skipping because alias '" + alias + "' not found, @Produces(...) missing?")
// .isTrue();
// log("depends on [" + alias + "](" + UseCaseTest.getAlias(alias).useCase().getSimpleName() + ".md)");
// }
}
private Set<String> allOf(final String value, final String explicitly, final String[] implicitly) {
final var all = new HashSet<String>();
if (!value.isEmpty()) {
all.add(value);
}
if (!explicitly.isEmpty()) {
all.add(explicitly);
}
all.addAll(asList(implicitly));
return all;
}
private String oneOf(final String one, final String another) {
if (one != null && another == null) {
return one;
} else if (one == null && another != null) {
return another;
}
throw new AssertionFailure("excactly one value required");
} }
static boolean containsAlias(final String alias) { static boolean containsAlias(final String alias) {

View File

@ -12,6 +12,7 @@ public class CreateExternalDebitorForPartner extends UseCase<CreateExternalDebit
public CreateExternalDebitorForPartner(final UseCaseTest testSuite, final String resultAlias) { public CreateExternalDebitorForPartner(final UseCaseTest testSuite, final String resultAlias) {
super(testSuite, resultAlias); super(testSuite, resultAlias);
requires("Person: Test AG");
requires("Person: Billing GmbH", alias -> new CreatePerson(testSuite, alias) requires("Person: Billing GmbH", alias -> new CreatePerson(testSuite, alias)
.given("personType", "LEGAL_PERSON") .given("personType", "LEGAL_PERSON")
.given("tradeName", "Billing GmbH") .given("tradeName", "Billing GmbH")

View File

@ -10,6 +10,8 @@ public class CreateSelfDebitorForPartner extends UseCase<CreateSelfDebitorForPar
public CreateSelfDebitorForPartner(final UseCaseTest testSuite, final String resultAlias) { public CreateSelfDebitorForPartner(final UseCaseTest testSuite, final String resultAlias) {
super(testSuite, resultAlias); super(testSuite, resultAlias);
requires("Person: Test AG");
} }
@Override @Override

View File

@ -9,17 +9,19 @@ public class CreateMembership extends UseCase<CreateMembership> {
public CreateMembership(final UseCaseTest testSuite) { public CreateMembership(final UseCaseTest testSuite) {
super(testSuite); super(testSuite);
requires("Partner: Test AG");
} }
@Override @Override
protected HttpResponse run() { protected HttpResponse run() {
keep("Membership: %{partnerName} 00", () -> keep("Membership: Test AG 00", () ->
httpPost("/api/hs/office/memberships", usingJsonBody(""" httpPost("/api/hs/office/memberships", usingJsonBody("""
{ {
"partnerUuid": ${Partner: Test AG}, "partnerUuid": ${Partner: Test AG},
"memberNumberSuffix": ${memberNumberSuffix}, "memberNumberSuffix": "00",
"validFrom": ${validFrom}, "validFrom": "2024-10-15",
"membershipFeeBillable": ${membershipFeeBillable} "membershipFeeBillable": "true"
} }
""")) """))
.expecting(HttpStatus.CREATED).expecting(ContentType.JSON) .expecting(HttpStatus.CREATED).expecting(ContentType.JSON)

View File

@ -24,7 +24,7 @@ public class CreatePartner extends UseCase<CreatePartner> {
.expecting(HttpStatus.CREATED).expecting(ContentType.JSON) .expecting(HttpStatus.CREATED).expecting(ContentType.JSON)
); );
keep("Contact: %{tradeName} - Board of Directors", () -> keep("Contact: %{tradeName} - Bord of Directors", () ->
httpPost("/api/hs/office/contacts", usingJsonBody(""" httpPost("/api/hs/office/contacts", usingJsonBody("""
{ {
"caption": ${contactCaption}, "caption": ${contactCaption},
@ -42,7 +42,7 @@ public class CreatePartner extends UseCase<CreatePartner> {
"partnerRel": { "partnerRel": {
"anchorUuid": ${Person: Hostsharing eG}, "anchorUuid": ${Person: Hostsharing eG},
"holderUuid": ${Person: %{tradeName}}, "holderUuid": ${Person: %{tradeName}},
"contactUuid": ${Contact: %{tradeName} - Board of Directors} "contactUuid": ${Contact: %{tradeName} - Bord of Directors}
}, },
"details": { "details": {
"registrationOffice": "Registergericht Hamburg", "registrationOffice": "Registergericht Hamburg",

View File

@ -12,8 +12,8 @@ public class DeletePartner extends UseCase<DeletePartner> {
requires("Partner: Delete AG", alias -> new CreatePartner(testSuite, alias) requires("Partner: Delete AG", alias -> new CreatePartner(testSuite, alias)
.given("personType", "LEGAL_PERSON") .given("personType", "LEGAL_PERSON")
.given("tradeName", "Delete AG") .given("tradeName", "Delete AG")
.given("contactCaption", "Delete AG - Board of Directors") .given("contactCaption", "Delete AG - Bord of Directors")
.given("emailAddress", "board-of-directors@delete-ag.example.org")); .given("emailAddress", "bord-of-directors@delete-ag.example.org"));
} }
@Override @Override