use AnnotationFinder to determine alias name from @Produces
This commit is contained in:
parent
87c9205fc7
commit
5605e8a8c1
@ -0,0 +1,47 @@
|
|||||||
|
package net.hostsharing.hsadminng.reflection;
|
||||||
|
|
||||||
|
import lombok.experimental.UtilityClass;
|
||||||
|
|
||||||
|
import java.lang.annotation.Annotation;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
import static java.util.Optional.empty;
|
||||||
|
|
||||||
|
@UtilityClass
|
||||||
|
public class AnnotationFinder {
|
||||||
|
|
||||||
|
public static <T extends Annotation> Optional<T> findCallerAnnotation(
|
||||||
|
final Class<T> annotationClassToFind,
|
||||||
|
final Class<? extends Annotation> annotationClassToStopLookup
|
||||||
|
) {
|
||||||
|
for (var element : Thread.currentThread().getStackTrace()) {
|
||||||
|
try {
|
||||||
|
final var clazz = Class.forName(element.getClassName());
|
||||||
|
final var method = getMethodFromStackElement(clazz, element);
|
||||||
|
|
||||||
|
// Check if the method is annotated with the desired annotation
|
||||||
|
if (method != null) {
|
||||||
|
if (method.isAnnotationPresent(annotationClassToFind)) {
|
||||||
|
return Optional.of(method.getAnnotation(annotationClassToFind));
|
||||||
|
} else if (method.isAnnotationPresent(annotationClassToStopLookup)) {
|
||||||
|
return empty();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (final ClassNotFoundException | NoSuchMethodException e) {
|
||||||
|
throw new RuntimeException(e); // FIXME: when does this happen?
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Method getMethodFromStackElement(Class<?> clazz, StackTraceElement element)
|
||||||
|
throws NoSuchMethodException {
|
||||||
|
for (var method : clazz.getDeclaredMethods()) {
|
||||||
|
if (method.getName().equals(element.getMethodName())) {
|
||||||
|
return method;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
@ -30,7 +30,7 @@ class HsOfficeUseCasesTest extends UseCaseTest {
|
|||||||
@Order(1010)
|
@Order(1010)
|
||||||
@Produces(explicitly = "Partner: Test AG", implicitly = "Person: Test AG")
|
@Produces(explicitly = "Partner: Test AG", implicitly = "Person: Test AG")
|
||||||
void shouldCreatePartner() {
|
void shouldCreatePartner() {
|
||||||
new CreatePartner(this, "Partner: Test AG")
|
new CreatePartner(this)
|
||||||
.given("partnerNumber", 31010)
|
.given("partnerNumber", 31010)
|
||||||
.given("personType", "LEGAL_PERSON")
|
.given("personType", "LEGAL_PERSON")
|
||||||
.given("tradeName", "Test AG")
|
.given("tradeName", "Test AG")
|
||||||
@ -73,7 +73,7 @@ class HsOfficeUseCasesTest extends UseCaseTest {
|
|||||||
@Requires("Person: Test AG")
|
@Requires("Person: Test AG")
|
||||||
@Produces("Debitor: Billing GmbH")
|
@Produces("Debitor: Billing GmbH")
|
||||||
void shouldCreateExternalDebitorForPartner() {
|
void shouldCreateExternalDebitorForPartner() {
|
||||||
new CreateExternalDebitorForPartner(this, "Debitor: Billing GmbH")
|
new CreateExternalDebitorForPartner(this)
|
||||||
.given("partnerPersonUuid", "%{Person: Test AG}")
|
.given("partnerPersonUuid", "%{Person: Test AG}")
|
||||||
.given("billingContactCaption", "Billing GmbH - billing department")
|
.given("billingContactCaption", "Billing GmbH - billing department")
|
||||||
.given("billingContactEmailAddress", "billing@test-ag.example.org")
|
.given("billingContactEmailAddress", "billing@test-ag.example.org")
|
||||||
@ -103,7 +103,7 @@ class HsOfficeUseCasesTest extends UseCaseTest {
|
|||||||
@Requires("Debitor: Test AG - main debitor")
|
@Requires("Debitor: Test AG - main debitor")
|
||||||
@Produces("SEPA-Mandate: Test AG")
|
@Produces("SEPA-Mandate: Test AG")
|
||||||
void shouldCreateSepaMandateForDebitor() {
|
void shouldCreateSepaMandateForDebitor() {
|
||||||
new CreateSepaMandataForDebitor(this, "SEPA-Mandate: Test AG")
|
new CreateSepaMandataForDebitor(this)
|
||||||
.given("debitor", "Test AG")
|
.given("debitor", "Test AG")
|
||||||
.given("memberNumberSuffix", "00")
|
.given("memberNumberSuffix", "00")
|
||||||
.given("validFrom", "2024-10-15")
|
.given("validFrom", "2024-10-15")
|
||||||
|
@ -4,7 +4,11 @@ import io.restassured.RestAssured;
|
|||||||
import io.restassured.http.ContentType;
|
import io.restassured.http.ContentType;
|
||||||
import io.restassured.response.Response;
|
import io.restassured.response.Response;
|
||||||
import io.restassured.response.ValidatableResponse;
|
import io.restassured.response.ValidatableResponse;
|
||||||
|
import net.hostsharing.hsadminng.reflection.AnnotationFinder;
|
||||||
import org.apache.commons.collections4.map.LinkedMap;
|
import org.apache.commons.collections4.map.LinkedMap;
|
||||||
|
import org.hibernate.AssertionFailure;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
import org.springframework.http.HttpMethod;
|
import org.springframework.http.HttpMethod;
|
||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
|
|
||||||
@ -16,6 +20,8 @@ import java.util.function.Supplier;
|
|||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
import static org.hamcrest.Matchers.startsWith;
|
import static org.hamcrest.Matchers.startsWith;
|
||||||
|
import static org.junit.platform.commons.util.StringUtils.isBlank;
|
||||||
|
import static org.junit.platform.commons.util.StringUtils.isNotBlank;
|
||||||
|
|
||||||
public abstract class UseCase<T extends UseCase<?>> {
|
public abstract class UseCase<T extends UseCase<?>> {
|
||||||
|
|
||||||
@ -26,7 +32,7 @@ public abstract class UseCase<T extends UseCase<?>> {
|
|||||||
private String nextTitle; // FIXME: ugly
|
private String nextTitle; // FIXME: ugly
|
||||||
|
|
||||||
public UseCase(final UseCaseTest testSuite) {
|
public UseCase(final UseCaseTest testSuite) {
|
||||||
this(testSuite, null);
|
this(testSuite, getResultAliasFromProducesAnnotationInCallStack());
|
||||||
}
|
}
|
||||||
|
|
||||||
public UseCase(final UseCaseTest testSuite, final String resultAlias) {
|
public UseCase(final UseCaseTest testSuite, final String resultAlias) {
|
||||||
@ -189,4 +195,19 @@ public abstract class UseCase<T extends UseCase<?>> {
|
|||||||
//noinspection unchecked
|
//noinspection unchecked
|
||||||
return (T) this;
|
return (T) this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static @Nullable String getResultAliasFromProducesAnnotationInCallStack() {
|
||||||
|
return AnnotationFinder.findCallerAnnotation(Produces.class, Test.class)
|
||||||
|
.map(produces -> oneOf(produces.value(), produces.explicitly()))
|
||||||
|
.orElse(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String oneOf(final String one, final String another) {
|
||||||
|
if (isNotBlank(one) && isBlank(another)) {
|
||||||
|
return one;
|
||||||
|
} else if ( isBlank(one) && isNotBlank(another)) {
|
||||||
|
return another;
|
||||||
|
}
|
||||||
|
throw new AssertionFailure("exactly one value required, but got '" + one + "' and '" + another + "'");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,6 @@ 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.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;
|
||||||
@ -148,15 +147,6 @@ public abstract class UseCaseTest extends ContextBasedTest {
|
|||||||
return all;
|
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) {
|
||||||
return aliases.containsKey(alias);
|
return aliases.containsKey(alias);
|
||||||
}
|
}
|
||||||
@ -177,10 +167,6 @@ public abstract class UseCaseTest extends ContextBasedTest {
|
|||||||
properties.put(name, (value instanceof String string) ? resolve(string) : value);
|
properties.put(name, (value instanceof String string) ? resolve(string) : value);
|
||||||
}
|
}
|
||||||
|
|
||||||
static LinkedHashMap<String, Object> properties() {
|
|
||||||
return new LinkedHashMap<>(properties);
|
|
||||||
}
|
|
||||||
|
|
||||||
static Map<String, Object> knowVariables() {
|
static Map<String, Object> knowVariables() {
|
||||||
final var map = new LinkedHashMap<String, Object>();
|
final var map = new LinkedHashMap<String, Object>();
|
||||||
UseCaseTest.aliases.forEach((key, value) -> map.put(key, value.uuid()));
|
UseCaseTest.aliases.forEach((key, value) -> map.put(key, value.uuid()));
|
||||||
|
@ -9,8 +9,8 @@ import static org.springframework.http.HttpStatus.CREATED;
|
|||||||
|
|
||||||
public class CreateExternalDebitorForPartner extends UseCase<CreateExternalDebitorForPartner> {
|
public class CreateExternalDebitorForPartner extends UseCase<CreateExternalDebitorForPartner> {
|
||||||
|
|
||||||
public CreateExternalDebitorForPartner(final UseCaseTest testSuite, final String resultAlias) {
|
public CreateExternalDebitorForPartner(final UseCaseTest testSuite) {
|
||||||
super(testSuite, resultAlias);
|
super(testSuite);
|
||||||
|
|
||||||
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")
|
||||||
|
@ -8,8 +8,8 @@ import static org.springframework.http.HttpStatus.CREATED;
|
|||||||
|
|
||||||
public class CreateSepaMandataForDebitor extends UseCase<CreateSepaMandataForDebitor> {
|
public class CreateSepaMandataForDebitor extends UseCase<CreateSepaMandataForDebitor> {
|
||||||
|
|
||||||
public CreateSepaMandataForDebitor(final UseCaseTest testSuite, final String resultAlias) {
|
public CreateSepaMandataForDebitor(final UseCaseTest testSuite) {
|
||||||
super(testSuite, resultAlias);
|
super(testSuite);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -11,6 +11,10 @@ public class CreatePartner extends UseCase<CreatePartner> {
|
|||||||
super(testSuite, resultAlias);
|
super(testSuite, resultAlias);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public CreatePartner(final UseCaseTest testSuite) {
|
||||||
|
super(testSuite);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected HttpResponse run() {
|
protected HttpResponse run() {
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user