feature/use-case-acceptance-tests #116
@ -3,6 +3,9 @@ package net.hostsharing.hsadminng.hs.office.usecases;
|
||||
import net.hostsharing.hsadminng.HsadminNgApplication;
|
||||
import net.hostsharing.hsadminng.hs.office.usecases.debitor.CreateExternalDebitorForPartner;
|
||||
import net.hostsharing.hsadminng.hs.office.usecases.debitor.CreateSelfDebitorForPartner;
|
||||
import net.hostsharing.hsadminng.hs.office.usecases.debitor.CreateSepaMandataForDebitor;
|
||||
import net.hostsharing.hsadminng.hs.office.usecases.debitor.DeleteSepaMandataForDebitor;
|
||||
import net.hostsharing.hsadminng.hs.office.usecases.debitor.InvalidateSepaMandataForDebitor;
|
||||
import net.hostsharing.hsadminng.hs.office.usecases.membership.CreateMembership;
|
||||
import net.hostsharing.hsadminng.hs.office.usecases.partner.CreatePartner;
|
||||
import net.hostsharing.hsadminng.hs.office.usecases.debitor.DeleteDebitor;
|
||||
@ -48,6 +51,7 @@ class HsOfficeUseCasesTest extends UseCaseTest {
|
||||
@Test
|
||||
@Order(2010)
|
||||
@Requires("Partner: Test AG")
|
||||
@Produces("Debitor: Test AG - main debitor")
|
||||
void shouldCreateSelfDebitorForPartner() {
|
||||
new CreateSelfDebitorForPartner(this, "Debitor: Test AG - main debitor")
|
||||
.given("partnerPersonUuid", "%{Person: Test AG}")
|
||||
@ -94,6 +98,39 @@ class HsOfficeUseCasesTest extends UseCaseTest {
|
||||
.doRun();
|
||||
}
|
||||
|
||||
@Test
|
||||
@Order(3100)
|
||||
@Requires("Debitor: Test AG - main debitor")
|
||||
@Produces("SEPA-Mandate: Test AG")
|
||||
void shouldCreateSepaMandateForDebitor() {
|
||||
new CreateSepaMandataForDebitor(this, "SEPA-Mandate: Test AG")
|
||||
.given("debitor", "Test AG")
|
||||
.given("memberNumberSuffix", "00")
|
||||
.given("validFrom", "2024-10-15")
|
||||
.given("membershipFeeBillable", "true")
|
||||
.doRun()
|
||||
.keep();
|
||||
}
|
||||
|
||||
@Test
|
||||
@Order(3108)
|
||||
@Requires("SEPA-Mandate: Test AG")
|
||||
void shouldInvalidateSepaMandateForDebitor() {
|
||||
new InvalidateSepaMandataForDebitor(this)
|
||||
.given("sepaMandateUuid", "%{SEPA-Mandate: Test AG}")
|
||||
.given("validUntil", "2025-09-30")
|
||||
.doRun();
|
||||
}
|
||||
|
||||
@Test
|
||||
@Order(3109)
|
||||
@Requires("SEPA-Mandate: Test AG")
|
||||
void shouldDeleteSepaMandateForDebitor() {
|
||||
new DeleteSepaMandataForDebitor(this)
|
||||
.given("sepaMandateUuid", "%{SEPA-Mandate: Test AG}")
|
||||
.doRun();
|
||||
}
|
||||
|
||||
@Test
|
||||
@Order(3000)
|
||||
@Requires("Partner: Test AG")
|
||||
|
@ -14,6 +14,7 @@ import java.util.UUID;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.hamcrest.Matchers.startsWith;
|
||||
|
||||
public abstract class UseCase<T extends UseCase<?>> {
|
||||
@ -87,6 +88,18 @@ public abstract class UseCase<T extends UseCase<?>> {
|
||||
return new HttpResponse(HttpMethod.POST, uriPath, body, response);
|
||||
}
|
||||
|
||||
public final HttpResponse httpPatch(final String uriPath, final JsonTemplate bodyJsonTemplate) {
|
||||
final var body = bodyJsonTemplate.resolvePlaceholders();
|
||||
final var uri = "http://localhost" + uriPath;
|
||||
final var response = RestAssured.given()
|
||||
.header("current-subject", UseCaseTest.RUN_AS_USER)
|
||||
.contentType(ContentType.JSON)
|
||||
.body(body)
|
||||
.port(testSuite.port)
|
||||
.when().patch(uri);
|
||||
return new HttpResponse(HttpMethod.PATCH, uriPath, body, response);
|
||||
}
|
||||
|
||||
public final HttpResponse httpDelete(final String uriPath) {
|
||||
final var response = RestAssured.given()
|
||||
.header("current-subject", UseCaseTest.RUN_AS_USER)
|
||||
@ -99,7 +112,7 @@ public abstract class UseCase<T extends UseCase<?>> {
|
||||
return UseCaseTest.getAlias(alias).uuid();
|
||||
}
|
||||
|
||||
static class JsonTemplate {
|
||||
public static class JsonTemplate {
|
||||
|
||||
private final String template;
|
||||
|
||||
@ -160,8 +173,10 @@ public abstract class UseCase<T extends UseCase<?>> {
|
||||
}
|
||||
|
||||
public void keep() {
|
||||
final var alias = nextTitle != null ? nextTitle : resultAlias;
|
||||
assertThat(alias).as("cannot keep result, no alias found").isNotNull();
|
||||
UseCaseTest.putAlias(
|
||||
nextTitle != null ? nextTitle : resultAlias,
|
||||
alias,
|
||||
new UseCaseTest.Alias<>(UseCase.this.getClass(), locationUuid));
|
||||
}
|
||||
}
|
||||
|
@ -19,12 +19,12 @@ import org.springframework.boot.test.web.server.LocalServerPort;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.stream.Collectors;
|
||||
@ -35,6 +35,7 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
public abstract class UseCaseTest extends ContextBasedTest {
|
||||
|
||||
final static String RUN_AS_USER = "superuser-alex@hostsharing.net"; // TODO.test: use global:AGENT when implemented
|
||||
//String producesAlias;
|
||||
|
||||
// @Getter
|
||||
// public static TestInfo currentTestInfo;
|
||||
@ -60,7 +61,7 @@ public abstract class UseCaseTest extends ContextBasedTest {
|
||||
@BeforeEach
|
||||
void init(final TestInfo testInfo) {
|
||||
createHostsharingPerson();
|
||||
callRequiredProducers(testInfo);
|
||||
testInfo.getTestMethod().ifPresent(this::callRequiredProducers);
|
||||
createTestLogMarkdownFile(testInfo);
|
||||
}
|
||||
|
||||
@ -102,36 +103,37 @@ public abstract class UseCaseTest extends ContextBasedTest {
|
||||
log("## Testcase " + testMethodName.replaceAll("([a-z])([A-Z]+)", "$1 $2"));
|
||||
}
|
||||
|
||||
private void callRequiredProducers(final TestInfo testInfo) throws IllegalAccessException, InvocationTargetException {
|
||||
final var testMethodRequired = testInfo.getTestMethod()
|
||||
@SneakyThrows
|
||||
private void callRequiredProducers(final Method currentTestMethod) {
|
||||
final var testMethodRequired = Optional.of(currentTestMethod)
|
||||
.map(m -> m.getAnnotation(Requires.class))
|
||||
.map(Requires::value)
|
||||
.orElse(null);
|
||||
if (testMethodRequired != null) {
|
||||
for (Method testMethod : getClass().getDeclaredMethods()) {
|
||||
final var producesAnnot = testMethod.getAnnotation(Produces.class);
|
||||
for (Method potentialProducerMethod : getClass().getDeclaredMethods()) {
|
||||
final var producesAnnot = potentialProducerMethod.getAnnotation(Produces.class);
|
||||
if (producesAnnot != null) {
|
||||
final var testMethodProduces = allOf(producesAnnot.value(), producesAnnot.explicitly(), producesAnnot.implicitly());
|
||||
final var testMethodProduces = allOf(
|
||||
producesAnnot.value(),
|
||||
producesAnnot.explicitly(),
|
||||
producesAnnot.implicitly());
|
||||
// @formatter:off
|
||||
if ( // that method can produce something required
|
||||
testMethodProduces.contains(testMethodRequired) &&
|
||||
|
||||
// and it does not produce anything we already have (would cause errors)
|
||||
SetUtils.intersection(testMethodProduces, knowVariables().keySet()).isEmpty())
|
||||
SetUtils.intersection(testMethodProduces, knowVariables().keySet()).isEmpty()
|
||||
) {
|
||||
// then we recursively produce the pre-requisites of the producer method
|
||||
callRequiredProducers(potentialProducerMethod);
|
||||
|
||||
// then we call the producer method
|
||||
testMethod.invoke(this);
|
||||
// and finally we call the producer method
|
||||
potentialProducerMethod.invoke(this);
|
||||
}
|
||||
// @formatter:on
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// 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) {
|
||||
|
@ -0,0 +1,39 @@
|
||||
package net.hostsharing.hsadminng.hs.office.usecases.debitor;
|
||||
|
||||
import net.hostsharing.hsadminng.hs.office.usecases.UseCase;
|
||||
import net.hostsharing.hsadminng.hs.office.usecases.UseCaseTest;
|
||||
|
||||
import static io.restassured.http.ContentType.JSON;
|
||||
import static org.springframework.http.HttpStatus.CREATED;
|
||||
|
||||
public class CreateSepaMandataForDebitor extends UseCase<CreateSepaMandataForDebitor> {
|
||||
|
||||
public CreateSepaMandataForDebitor(final UseCaseTest testSuite, final String resultAlias) {
|
||||
super(testSuite, resultAlias);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected HttpResponse run() {
|
||||
keep("BankAccount: Test AG - debit bank account", () ->
|
||||
httpPost("/api/hs/office/bankaccounts", usingJsonBody("""
|
||||
{
|
||||
"holder": "Test AG - debit bank account",
|
||||
"iban": "DE02701500000000594937",
|
||||
"bic": "SSKMDEMM"
|
||||
}
|
||||
"""))
|
||||
.expecting(CREATED).expecting(JSON)
|
||||
);
|
||||
|
||||
return httpPost("/api/hs/office/sepamandates", usingJsonBody("""
|
||||
{
|
||||
"debitorUuid": ${Debitor: Test AG - main debitor},
|
||||
"bankAccountUuid": ${BankAccount: Test AG - debit bank account},
|
||||
"reference": "Test AG - main debitor",
|
||||
"agreement": "2022-10-12",
|
||||
"validFrom": "2022-10-13"
|
||||
}
|
||||
"""))
|
||||
.expecting(CREATED).expecting(JSON);
|
||||
}
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
package net.hostsharing.hsadminng.hs.office.usecases.debitor;
|
||||
|
||||
import net.hostsharing.hsadminng.hs.office.usecases.UseCase;
|
||||
import net.hostsharing.hsadminng.hs.office.usecases.UseCaseTest;
|
||||
import org.springframework.http.HttpStatus;
|
||||
|
||||
|
||||
public class DeleteSepaMandataForDebitor extends UseCase<DeleteSepaMandataForDebitor> {
|
||||
|
||||
public DeleteSepaMandataForDebitor(final UseCaseTest testSuite) {
|
||||
super(testSuite);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected HttpResponse run() {
|
||||
httpDelete("/api/hs/office/sepamandates/" + uuid("SEPA-Mandate: Test AG"))
|
||||
.expecting(HttpStatus.NO_CONTENT);
|
||||
return null;
|
||||
}
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
package net.hostsharing.hsadminng.hs.office.usecases.debitor;
|
||||
|
||||
import net.hostsharing.hsadminng.hs.office.usecases.UseCase;
|
||||
import net.hostsharing.hsadminng.hs.office.usecases.UseCaseTest;
|
||||
|
||||
import static io.restassured.http.ContentType.JSON;
|
||||
import static org.springframework.http.HttpStatus.OK;
|
||||
|
||||
public class InvalidateSepaMandataForDebitor extends UseCase<InvalidateSepaMandataForDebitor> {
|
||||
|
||||
public InvalidateSepaMandataForDebitor(final UseCaseTest testSuite) {
|
||||
super(testSuite);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected HttpResponse run() {
|
||||
|
||||
return httpPatch("/api/hs/office/sepamandates/" + uuid("SEPA-Mandate: Test AG"), usingJsonBody("""
|
||||
{
|
||||
"validUntil": ${validUntil}
|
||||
}
|
||||
"""))
|
||||
.expecting(OK).expecting(JSON);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user