add testCoopShares-scenario-tests - WIP
This commit is contained in:
parent
9531f6a881
commit
e8b74ad1c0
@ -46,6 +46,7 @@ public class CustomErrorResponse {
|
||||
this.path = path;
|
||||
this.statusCode = status.value();
|
||||
this.statusPhrase = status.getReasonPhrase();
|
||||
// HOWTO: debug serverside error response - set a breakpoint here
|
||||
this.message = message.startsWith("ERROR: [") ? message : "ERROR: [" + statusCode + "] " + message;
|
||||
}
|
||||
}
|
||||
|
@ -16,6 +16,8 @@ import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.function.BiConsumer;
|
||||
|
||||
import static java.util.Optional.ofNullable;
|
||||
|
||||
@RestController
|
||||
|
||||
public class HsOfficeMembershipController implements HsOfficeMembershipsApi {
|
||||
@ -39,7 +41,8 @@ public class HsOfficeMembershipController implements HsOfficeMembershipsApi {
|
||||
context.define(currentSubject, assumedRoles);
|
||||
|
||||
final var entities = ( memberNumber != null)
|
||||
? List.of(membershipRepo.findMembershipByMemberNumber(memberNumber))
|
||||
// FIXME: RestTest for the case that findMembershipByMemberNumber returns null
|
||||
? ofNullable(membershipRepo.findMembershipByMemberNumber(memberNumber)).stream().toList()
|
||||
: membershipRepo.findMembershipsByOptionalPartnerUuid(partnerUuid);
|
||||
|
||||
final var resources = mapper.mapList(entities, HsOfficeMembershipResource.class,
|
||||
|
@ -12,6 +12,7 @@ import net.hostsharing.hsadminng.hs.office.scenarios.debitor.FinallyDeleteSepaMa
|
||||
import net.hostsharing.hsadminng.hs.office.scenarios.debitor.DontDeleteDefaultDebitor;
|
||||
import net.hostsharing.hsadminng.hs.office.scenarios.debitor.InvalidateSepaMandateForDebitor;
|
||||
import net.hostsharing.hsadminng.hs.office.scenarios.membership.CancelMembership;
|
||||
import net.hostsharing.hsadminng.hs.office.scenarios.membership.CoopSharesTransactionUseCase;
|
||||
import net.hostsharing.hsadminng.hs.office.scenarios.membership.CreateMembership;
|
||||
import net.hostsharing.hsadminng.hs.office.scenarios.partner.AddOperationsContactToPartner;
|
||||
import net.hostsharing.hsadminng.hs.office.scenarios.partner.CreatePartner;
|
||||
@ -49,7 +50,7 @@ class HsOfficeScenarioTests extends ScenarioTest {
|
||||
|
||||
@Test
|
||||
@Order(1010)
|
||||
@Produces(explicitly = "Partner: Test AG", implicitly = {"Person: Test AG", "Contact: Test AG - Hamburg"})
|
||||
@Produces(explicitly = "Partner: P-31010 - Test AG", implicitly = {"Person: Test AG", "Contact: Test AG - Hamburg"})
|
||||
void shouldCreateLegalPersonAsPartner() {
|
||||
new CreatePartner(this)
|
||||
.given("partnerNumber", 31010)
|
||||
@ -71,7 +72,7 @@ class HsOfficeScenarioTests extends ScenarioTest {
|
||||
|
||||
@Test
|
||||
@Order(1011)
|
||||
@Produces(explicitly = "Partner: Michelle Matthieu", implicitly = {"Person: Michelle Matthieu", "Contact: Michelle Matthieu"})
|
||||
@Produces(explicitly = "Partner: P-31011 - Michelle Matthieu", implicitly = {"Person: Michelle Matthieu", "Contact: Michelle Matthieu"})
|
||||
void shouldCreateNaturalPersonAsPartner() {
|
||||
new CreatePartner(this)
|
||||
.given("partnerNumber", 31011)
|
||||
@ -148,7 +149,7 @@ class HsOfficeScenarioTests extends ScenarioTest {
|
||||
|
||||
@Test
|
||||
@Order(1100)
|
||||
@Requires("Partner: Michelle Matthieu")
|
||||
@Requires("Partner: P-31011 - Michelle Matthieu")
|
||||
void shouldAmendContactData() {
|
||||
new AmendContactData(this)
|
||||
.given("partnerName", "Matthieu")
|
||||
@ -158,7 +159,7 @@ class HsOfficeScenarioTests extends ScenarioTest {
|
||||
|
||||
@Test
|
||||
@Order(1101)
|
||||
@Requires("Partner: Michelle Matthieu")
|
||||
@Requires("Partner: P-31011 - Michelle Matthieu")
|
||||
void shouldAddPhoneNumberToContactData() {
|
||||
new AddPhoneNumberToContactData(this)
|
||||
.given("partnerName", "Matthieu")
|
||||
@ -169,7 +170,7 @@ class HsOfficeScenarioTests extends ScenarioTest {
|
||||
|
||||
@Test
|
||||
@Order(1102)
|
||||
@Requires("Partner: Michelle Matthieu")
|
||||
@Requires("Partner: P-31011 - Michelle Matthieu")
|
||||
void shouldRemovePhoneNumberFromContactData() {
|
||||
new RemovePhoneNumberFromContactData(this)
|
||||
.given("partnerName", "Matthieu")
|
||||
@ -179,7 +180,7 @@ class HsOfficeScenarioTests extends ScenarioTest {
|
||||
|
||||
@Test
|
||||
@Order(1103)
|
||||
@Requires("Partner: Test AG")
|
||||
@Requires("Partner: P-31010 - Test AG")
|
||||
void shouldReplaceContactData() {
|
||||
new ReplaceContactData(this)
|
||||
.given("partnerName", "Test AG")
|
||||
@ -201,7 +202,7 @@ class HsOfficeScenarioTests extends ScenarioTest {
|
||||
|
||||
@Test
|
||||
@Order(1201)
|
||||
@Requires("Partner: Michelle Matthieu")
|
||||
@Requires("Partner: P-31011 - Michelle Matthieu")
|
||||
void shouldUpdatePersonData() {
|
||||
new ShouldUpdatePersonData(this)
|
||||
.given("oldFamilyName", "Matthieu")
|
||||
@ -211,7 +212,7 @@ class HsOfficeScenarioTests extends ScenarioTest {
|
||||
|
||||
@Test
|
||||
@Order(2010)
|
||||
@Requires("Partner: Test AG")
|
||||
@Requires("Partner: P-31010 - Test AG")
|
||||
@Produces("Debitor: Test AG - main debitor")
|
||||
void shouldCreateSelfDebitorForPartner() {
|
||||
new CreateSelfDebitorForPartner(this, "Debitor: Test AG - main debitor")
|
||||
@ -313,7 +314,7 @@ class HsOfficeScenarioTests extends ScenarioTest {
|
||||
|
||||
@Test
|
||||
@Order(4000)
|
||||
@Requires("Partner: Test AG")
|
||||
@Requires("Partner: P-31010 - Test AG")
|
||||
@Produces("Membership: Test AG 00")
|
||||
void shouldCreateMembershipForPartner() {
|
||||
new CreateMembership(this)
|
||||
@ -326,6 +327,51 @@ class HsOfficeScenarioTests extends ScenarioTest {
|
||||
.keep();
|
||||
}
|
||||
|
||||
@Test
|
||||
@Order(4200)
|
||||
@Requires("Membership: Test AG 00")
|
||||
@Produces("Coop-Shares SUBSCRIPTION Transaction")
|
||||
void testCoopSharesSubscriptionTransaction() {
|
||||
new CoopSharesTransactionUseCase(this)
|
||||
.given("memberNumber", "3101000")
|
||||
.given("transactionType", "SUBSCRIPTION")
|
||||
.given("reference", "sign 2024-01-15")
|
||||
.given("shareCount", "100")
|
||||
.given("comment", "Signing the Membership")
|
||||
.given("transactionDate", "2024-01-15")
|
||||
.doRun();
|
||||
}
|
||||
|
||||
@Test
|
||||
@Order(4201)
|
||||
@Requires("Coop-Shares SUBSCRIPTION Transaction")
|
||||
@Produces("Coop-Shares ADJUSTMENT Transaction")
|
||||
void testCoopSharesAdjustmentTransaction() {
|
||||
new CoopSharesTransactionUseCase(this)
|
||||
.given("memberNumber", "3102000")
|
||||
.given("transactionType", "ADJUSTMENT")
|
||||
.given("reference", "adjust 2024-01-16")
|
||||
.given("shareCount", "-90")
|
||||
.given("comment", "Cancelling 90 Shares, correcting wrong number of digits in subscription")
|
||||
.given("transactionDate", "2024-01-16")
|
||||
.doRun();
|
||||
}
|
||||
|
||||
@Test
|
||||
@Order(4202)
|
||||
@Requires("Coop-Shares SUBSCRIPTION Transaction")
|
||||
@Produces("Coop-Shares CANCELLATION Transaction")
|
||||
void testCoopSharesCancellationTransaction() {
|
||||
new CoopSharesTransactionUseCase(this)
|
||||
.given("memberNumber", "3102000")
|
||||
.given("transactionType", "CANCELLATION")
|
||||
.given("reference", "cancel 2024-01-15")
|
||||
.given("shareCount", "8")
|
||||
.given("comment", "Cancelling 8 Shares")
|
||||
.given("transactionDate", "2024-02-15")
|
||||
.doRun();
|
||||
}
|
||||
|
||||
@Test
|
||||
@Order(4900)
|
||||
@Requires("Membership: Test AG 00")
|
||||
|
@ -4,6 +4,8 @@ import net.hostsharing.hsadminng.hs.office.scenarios.UseCase.HttpResponse;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.fail;
|
||||
|
||||
public class PathAssertion {
|
||||
|
||||
private final String path;
|
||||
@ -14,10 +16,25 @@ public class PathAssertion {
|
||||
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
public Consumer<UseCase.HttpResponse> contains(final String resolvableValue) {
|
||||
return response -> response.path(path).contains(ScenarioTest.resolve(resolvableValue));
|
||||
return response -> {
|
||||
try {
|
||||
// FIXME: typed check instead of .map(Object::toString) possible?
|
||||
response.path(path).map(Object::toString).contains(ScenarioTest.resolve(resolvableValue));
|
||||
} catch (final AssertionError e) {
|
||||
// without this, the error message is often lacking important context
|
||||
fail(e.getMessage() + " in `path(\"" + path + "\").contains(\"" + resolvableValue + "\")`" );
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public Consumer<HttpResponse> doesNotExist() {
|
||||
return response -> response.path(path).isNull(); // here, null Optional means key not found in JSON
|
||||
return response -> {
|
||||
try {
|
||||
response.path(path).isNull(); // here, null Optional means key not found in JSON
|
||||
} catch (final AssertionError e) {
|
||||
// without this, the error message is often lacking important context
|
||||
fail(e.getMessage() + " in `path(\"" + path + "\").doesNotExist()`" );
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -302,16 +302,17 @@ public abstract class UseCase<T extends UseCase<?>> {
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
public Optional<String> getFromBodyAsOptional(final String path) {
|
||||
public <T> Optional<T> getFromBodyAsOptional(final String path) {
|
||||
try {
|
||||
return Optional.ofNullable(JsonPath.parse(response.body()).read(ScenarioTest.resolve(path)));
|
||||
} catch (final Exception e) {
|
||||
// FIXME: catch more precise exception class
|
||||
return null; // means the property did not exist at all, not that it was there with value null
|
||||
}
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
public OptionalAssert<String> path(final String path) {
|
||||
public <T> OptionalAssert<T> path(final String path) {
|
||||
return assertThat(getFromBodyAsOptional(path));
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,51 @@
|
||||
package net.hostsharing.hsadminng.hs.office.scenarios.membership;
|
||||
|
||||
import io.restassured.http.ContentType;
|
||||
import net.hostsharing.hsadminng.hs.office.scenarios.UseCase;
|
||||
import net.hostsharing.hsadminng.hs.office.scenarios.ScenarioTest;
|
||||
import org.springframework.http.HttpStatus;
|
||||
|
||||
import static io.restassured.http.ContentType.JSON;
|
||||
import static org.springframework.http.HttpStatus.OK;
|
||||
|
||||
public class CoopSharesTransactionUseCase extends UseCase<CoopSharesTransactionUseCase> {
|
||||
|
||||
public CoopSharesTransactionUseCase(final ScenarioTest testSuite) {
|
||||
super(testSuite);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected HttpResponse run() {
|
||||
|
||||
obtain("membershipUuid", () ->
|
||||
httpGet("/api/hs/office/memberships?memberNumber=&{memberNumber}")
|
||||
.expecting(OK).expecting(JSON).expectArrayElements(1),
|
||||
response -> response.getFromBody("$[0].uuid")
|
||||
);
|
||||
|
||||
return httpPost("/api/hs/office/coopsharestransactions", usingJsonBody("""
|
||||
{
|
||||
"membership.uuid": ${membershipUuid},
|
||||
"transactionType": ${transactionType},
|
||||
"reference": ${reference},
|
||||
"shareCount": ${shareCount},
|
||||
"comment": ${comment},
|
||||
"valueDate": ${transactionDate}
|
||||
}
|
||||
"""))
|
||||
.expecting(HttpStatus.CREATED).expecting(ContentType.JSON);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void verify(final HttpResponse response) {
|
||||
verify("Verify Coop-Shares %{transactionType}-Transaction",
|
||||
() -> httpGet("/api/hs/office/coopsharestransactions/" + response.getLocationUuid())
|
||||
.expecting(HttpStatus.OK).expecting(ContentType.JSON),
|
||||
// path("transactionType").contains("%{transactionType}"),
|
||||
// path("memberNumber").contains("%{memberNumber}"),
|
||||
path("shareCount").contains("%{shareCount}"),
|
||||
path("comment").contains("%{comment}"),
|
||||
path("valueDate").contains("%{transactionDate}")
|
||||
);
|
||||
}
|
||||
}
|
@ -16,9 +16,11 @@ public class CreateMembership extends UseCase<CreateMembership> {
|
||||
|
||||
@Override
|
||||
protected HttpResponse run() {
|
||||
// FIXME: httpGet "partner.uuid": ${Partner: Test AG}
|
||||
|
||||
return httpPost("/api/hs/office/memberships", usingJsonBody("""
|
||||
{
|
||||
"partner.uuid": ${Partner: Test AG},
|
||||
"partner.uuid": ${Partner: P-31010 - Test AG},
|
||||
"memberNumberSuffix": ${memberNumberSuffix},
|
||||
"status": "ACTIVE",
|
||||
"validFrom": ${validFrom},
|
||||
|
Loading…
Reference in New Issue
Block a user