fix memberhip acceptance tests

This commit is contained in:
Michael Hoennig 2024-03-22 06:32:42 +01:00
parent 9b8b50b065
commit f54a699e8c

View File

@ -5,7 +5,6 @@ import io.restassured.RestAssured;
import io.restassured.http.ContentType; import io.restassured.http.ContentType;
import net.hostsharing.hsadminng.HsadminNgApplication; import net.hostsharing.hsadminng.HsadminNgApplication;
import net.hostsharing.hsadminng.context.Context; import net.hostsharing.hsadminng.context.Context;
import net.hostsharing.hsadminng.hs.office.debitor.HsOfficeDebitorRepository;
import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerRepository; import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerRepository;
import net.hostsharing.hsadminng.hs.office.test.ContextBasedTestWithCleanup; import net.hostsharing.hsadminng.hs.office.test.ContextBasedTestWithCleanup;
import net.hostsharing.test.Accepts; import net.hostsharing.test.Accepts;
@ -24,6 +23,7 @@ import jakarta.persistence.PersistenceContext;
import java.time.LocalDate; import java.time.LocalDate;
import java.util.UUID; import java.util.UUID;
import static net.hostsharing.hsadminng.hs.office.membership.HsOfficeReasonForTermination.CANCELLATION;
import static net.hostsharing.hsadminng.hs.office.membership.HsOfficeReasonForTermination.NONE; import static net.hostsharing.hsadminng.hs.office.membership.HsOfficeReasonForTermination.NONE;
import static net.hostsharing.test.IsValidUuidMatcher.isUuidValid; import static net.hostsharing.test.IsValidUuidMatcher.isUuidValid;
import static net.hostsharing.test.JsonMatcher.lenientlyEquals; import static net.hostsharing.test.JsonMatcher.lenientlyEquals;
@ -51,9 +51,6 @@ class HsOfficeMembershipControllerAcceptanceTest extends ContextBasedTestWithCle
@Autowired @Autowired
HsOfficeMembershipRepository membershipRepo; HsOfficeMembershipRepository membershipRepo;
@Autowired
HsOfficeDebitorRepository debitorRepo;
@Autowired @Autowired
HsOfficePartnerRepository partnerRepo; HsOfficePartnerRepository partnerRepo;
@ -82,8 +79,7 @@ class HsOfficeMembershipControllerAcceptanceTest extends ContextBasedTestWithCle
.body("", lenientlyEquals(""" .body("", lenientlyEquals("""
[ [
{ {
"partner": { "person": { "tradeName": "First GmbH" } }, "partner": { "partnerNumber": 10001 },
"mainDebitor": { "debitorNumber": 1000111 },
"memberNumber": 1000101, "memberNumber": 1000101,
"memberNumberSuffix": "01", "memberNumberSuffix": "01",
"validFrom": "2022-10-01", "validFrom": "2022-10-01",
@ -91,8 +87,7 @@ class HsOfficeMembershipControllerAcceptanceTest extends ContextBasedTestWithCle
"reasonForTermination": "NONE" "reasonForTermination": "NONE"
}, },
{ {
"partner": { "person": { "tradeName": "Second e.K." } }, "partner": { "partnerNumber": 10002 },
"mainDebitor": { "debitorNumber": 1000212 },
"memberNumber": 1000202, "memberNumber": 1000202,
"memberNumberSuffix": "02", "memberNumberSuffix": "02",
"validFrom": "2022-10-01", "validFrom": "2022-10-01",
@ -100,8 +95,7 @@ class HsOfficeMembershipControllerAcceptanceTest extends ContextBasedTestWithCle
"reasonForTermination": "NONE" "reasonForTermination": "NONE"
}, },
{ {
"partner": { "person": { "tradeName": "Third OHG" } }, "partner": { "partnerNumber": 10003 },
"mainDebitor": { "debitorNumber": 1000313 },
"memberNumber": 1000303, "memberNumber": 1000303,
"memberNumberSuffix": "03", "memberNumberSuffix": "03",
"validFrom": "2022-10-01", "validFrom": "2022-10-01",
@ -132,8 +126,7 @@ class HsOfficeMembershipControllerAcceptanceTest extends ContextBasedTestWithCle
.body("", lenientlyEquals(""" .body("", lenientlyEquals("""
[ [
{ {
"partner": { "person": { "tradeName": "First GmbH" } }, "partner": { "partnerNumber": 10001 },
"mainDebitor": { "debitorNumber": 1000111 },
"memberNumber": 1000101, "memberNumber": 1000101,
"memberNumberSuffix": "01", "memberNumberSuffix": "01",
"validFrom": "2022-10-01", "validFrom": "2022-10-01",
@ -161,8 +154,7 @@ class HsOfficeMembershipControllerAcceptanceTest extends ContextBasedTestWithCle
.body("", lenientlyEquals(""" .body("", lenientlyEquals("""
[ [
{ {
"partner": { "person": { "tradeName": "Second e.K." } }, "partner": { "partnerNumber": 10002 },
"mainDebitor": { "debitorNumber": 1000212 },
"memberNumber": 1000202, "memberNumber": 1000202,
"memberNumberSuffix": "02", "memberNumberSuffix": "02",
"validFrom": "2022-10-01", "validFrom": "2022-10-01",
@ -184,7 +176,6 @@ class HsOfficeMembershipControllerAcceptanceTest extends ContextBasedTestWithCle
context.define("superuser-alex@hostsharing.net"); context.define("superuser-alex@hostsharing.net");
final var givenPartner = partnerRepo.findPartnerByOptionalNameLike("Third").get(0); final var givenPartner = partnerRepo.findPartnerByOptionalNameLike("Third").get(0);
final var givenDebitor = debitorRepo.findDebitorByOptionalNameLike("Third").get(0);
final var givenMemberSuffix = TEMP_MEMBER_NUMBER_SUFFIX; final var givenMemberSuffix = TEMP_MEMBER_NUMBER_SUFFIX;
final var expectedMemberNumber = Integer.parseInt(givenPartner.getPartnerNumber() + TEMP_MEMBER_NUMBER_SUFFIX); final var expectedMemberNumber = Integer.parseInt(givenPartner.getPartnerNumber() + TEMP_MEMBER_NUMBER_SUFFIX);
@ -195,12 +186,11 @@ class HsOfficeMembershipControllerAcceptanceTest extends ContextBasedTestWithCle
.body(""" .body("""
{ {
"partnerUuid": "%s", "partnerUuid": "%s",
"mainDebitorUuid": "%s",
"memberNumberSuffix": "%s", "memberNumberSuffix": "%s",
"validFrom": "2022-10-13", "validFrom": "2022-10-13",
"membershipFeeBillable": "true" "membershipFeeBillable": "true"
} }
""".formatted(givenPartner.getUuid(), givenDebitor.getUuid(), givenMemberSuffix)) """.formatted(givenPartner.getUuid(), givenMemberSuffix))
.port(port) .port(port)
.when() .when()
.post("http://localhost/api/hs/office/memberships") .post("http://localhost/api/hs/office/memberships")
@ -208,9 +198,7 @@ class HsOfficeMembershipControllerAcceptanceTest extends ContextBasedTestWithCle
.statusCode(201) .statusCode(201)
.contentType(ContentType.JSON) .contentType(ContentType.JSON)
.body("uuid", isUuidValid()) .body("uuid", isUuidValid())
.body("mainDebitor.debitorNumber", is(givenDebitor.getDebitorNumber())) .body("partner.partnerNumber", is(10003))
.body("mainDebitor.debitorNumberSuffix", is((int) givenDebitor.getDebitorNumberSuffix()))
.body("partner.person.tradeName", is("Third OHG"))
.body("memberNumber", is(expectedMemberNumber)) .body("memberNumber", is(expectedMemberNumber))
.body("memberNumberSuffix", is(givenMemberSuffix)) .body("memberNumberSuffix", is(givenMemberSuffix))
.body("validFrom", is("2022-10-13")) .body("validFrom", is("2022-10-13"))
@ -246,8 +234,7 @@ class HsOfficeMembershipControllerAcceptanceTest extends ContextBasedTestWithCle
.contentType("application/json") .contentType("application/json")
.body("", lenientlyEquals(""" .body("", lenientlyEquals("""
{ {
"partner": { "person": { "tradeName": "First GmbH" } }, "partner": { "partnerNumber": 10001 },
"mainDebitor": { "debitorNumber": 1000111 },
"memberNumber": 1000101, "memberNumber": 1000101,
"memberNumberSuffix": "01", "memberNumberSuffix": "01",
"validFrom": "2022-10-01", "validFrom": "2022-10-01",
@ -275,14 +262,14 @@ class HsOfficeMembershipControllerAcceptanceTest extends ContextBasedTestWithCle
@Test @Test
@Accepts({ "Membership:X(Access Control)" }) @Accepts({ "Membership:X(Access Control)" })
void debitorAgentUser_canGetRelatedMembership() { void parnerRelAgent_canGetRelatedMembership() {
context.define("superuser-alex@hostsharing.net"); context.define("superuser-alex@hostsharing.net");
final var givenMembershipUuid = membershipRepo.findMembershipByMemberNumber(1000303).getUuid(); final var givenMembershipUuid = membershipRepo.findMembershipByMemberNumber(1000303).getUuid();
RestAssured // @formatter:off RestAssured // @formatter:off
.given() .given()
.header("current-user", "superuser-alex@hostsharing.net") .header("current-user", "superuser-alex@hostsharing.net")
.header("assumed-roles", "hs_office_debitor#1000313:ThirdOHG-thirdcontact.agent") .header("assumed-roles", "hs_office_relationship#HostsharingeG-with-PARTNER-ThirdOHG.agent")
.port(port) .port(port)
.when() .when()
.get("http://localhost/api/hs/office/memberships/" + givenMembershipUuid) .get("http://localhost/api/hs/office/memberships/" + givenMembershipUuid)
@ -291,11 +278,7 @@ class HsOfficeMembershipControllerAcceptanceTest extends ContextBasedTestWithCle
.contentType("application/json") .contentType("application/json")
.body("", lenientlyEquals(""" .body("", lenientlyEquals("""
{ {
"partner": { "person": { "tradeName": "Third OHG" } }, "partner": { "partnerNumber": 10003 },
"mainDebitor": {
"debitorNumber": 1000313,
"billingContact": { "label": "third contact" }
},
"memberNumber": 1000303, "memberNumber": 1000303,
"memberNumberSuffix": "03", "memberNumberSuffix": "03",
"validFrom": "2022-10-01", "validFrom": "2022-10-01",
@ -314,7 +297,7 @@ class HsOfficeMembershipControllerAcceptanceTest extends ContextBasedTestWithCle
void globalAdmin_canPatchValidToOfArbitraryMembership() { void globalAdmin_canPatchValidToOfArbitraryMembership() {
context.define("superuser-alex@hostsharing.net"); context.define("superuser-alex@hostsharing.net");
final var givenMembership = givenSomeTemporaryMembershipBessler(); final var givenMembership = givenSomeTemporaryMembershipBessler("First");
final var location = RestAssured // @formatter:off final var location = RestAssured // @formatter:off
.given() .given()
@ -333,7 +316,7 @@ class HsOfficeMembershipControllerAcceptanceTest extends ContextBasedTestWithCle
.statusCode(200) .statusCode(200)
.contentType(ContentType.JSON) .contentType(ContentType.JSON)
.body("uuid", isUuidValid()) .body("uuid", isUuidValid())
.body("partner.person.tradeName", is(givenMembership.getPartner().getPartnerRole().getRelHolder().getTradeName())) .body("partner.partnerNumber", is(givenMembership.getPartner().getPartnerNumber()))
.body("memberNumberSuffix", is(givenMembership.getMemberNumberSuffix())) .body("memberNumberSuffix", is(givenMembership.getMemberNumberSuffix()))
.body("validFrom", is("2022-11-01")) .body("validFrom", is("2022-11-01"))
.body("validTo", is("2023-12-31")) .body("validTo", is("2023-12-31"))
@ -343,70 +326,31 @@ class HsOfficeMembershipControllerAcceptanceTest extends ContextBasedTestWithCle
// finally, the Membership is actually updated // finally, the Membership is actually updated
assertThat(membershipRepo.findByUuid(givenMembership.getUuid())).isPresent().get() assertThat(membershipRepo.findByUuid(givenMembership.getUuid())).isPresent().get()
.matches(mandate -> { .matches(mandate -> {
assertThat(mandate.getPartner().toShortString()).isEqualTo("LP First GmbH"); assertThat(mandate.getPartner().toShortString()).isEqualTo("P-10001");
assertThat(mandate.getMemberNumberSuffix()).isEqualTo(givenMembership.getMemberNumberSuffix()); assertThat(mandate.getMemberNumberSuffix()).isEqualTo(givenMembership.getMemberNumberSuffix());
assertThat(mandate.getValidity().asString()).isEqualTo("[2022-11-01,2024-01-01)"); assertThat(mandate.getValidity().asString()).isEqualTo("[2022-11-01,2024-01-01)");
assertThat(mandate.getReasonForTermination()).isEqualTo(HsOfficeReasonForTermination.CANCELLATION); assertThat(mandate.getReasonForTermination()).isEqualTo(CANCELLATION);
return true; return true;
}); });
} }
@Test @Test
void globalAdmin_canPatchMainDebitorOfArbitraryMembership() { void partnerRelAgent_canPatchValidityOfRelatedMembership() {
context.define("superuser-alex@hostsharing.net"); // given
final var givenMembership = givenSomeTemporaryMembershipBessler(); final var givenPartnerAgent = "hs_office_relationship#HostsharingeG-with-PARTNER-FirstGmbH.agent";
final var givenNewMainDebitor = debitorRepo.findDebitorByDebitorNumber(1000313).get(0); context.define("superuser-alex@hostsharing.net", givenPartnerAgent);
final var givenMembership = givenSomeTemporaryMembershipBessler("First");
// when
RestAssured // @formatter:off RestAssured // @formatter:off
.given() .given()
.header("current-user", "superuser-alex@hostsharing.net") .header("current-user", "superuser-alex@hostsharing.net")
.header("assumed-roles", givenPartnerAgent)
.contentType(ContentType.JSON) .contentType(ContentType.JSON)
.body(""" .body("""
{ {
"mainDebitorUuid": "%s" "validTo": "2024-01-01",
}
""".formatted(givenNewMainDebitor.getUuid()))
.port(port)
.when()
.patch("http://localhost/api/hs/office/memberships/" + givenMembership.getUuid())
.then().log().all().assertThat()
.statusCode(200)
.contentType(ContentType.JSON)
.body("uuid", isUuidValid())
.body("partner.person.tradeName", is(givenMembership.getPartner().getPartnerRole().getRelHolder().getTradeName()))
.body("mainDebitor.debitorNumber", is(1000313))
.body("memberNumberSuffix", is(givenMembership.getMemberNumberSuffix()))
.body("validFrom", is("2022-11-01"))
.body("validTo", nullValue())
.body("reasonForTermination", is("NONE"));
// @formatter:on
// finally, the Membership is actually updated
assertThat(membershipRepo.findByUuid(givenMembership.getUuid())).isPresent().get()
.matches(mandate -> {
assertThat(mandate.getPartner().toShortString()).isEqualTo("LP First GmbH");
assertThat(mandate.getMemberNumberSuffix()).isEqualTo(givenMembership.getMemberNumberSuffix());
assertThat(mandate.getValidity().asString()).isEqualTo("[2022-11-01,)");
assertThat(mandate.getReasonForTermination()).isEqualTo(NONE);
return true;
});
}
@Test
void partnerAgent_canViewButNotPatchValidityOfRelatedMembership() {
context.define("superuser-alex@hostsharing.net", "hs_office_partner#10001:FirstGmbH-firstcontact.agent");
final var givenMembership = givenSomeTemporaryMembershipBessler();
final var location = RestAssured // @formatter:off
.given()
.header("current-user", "superuser-alex@hostsharing.net")
.header("assumed-roles", "hs_office_partner#10001:FirstGmbH-firstcontact.agent")
.contentType(ContentType.JSON)
.body("""
{
"validTo": "2023-12-31",
"reasonForTermination": "CANCELLATION" "reasonForTermination": "CANCELLATION"
} }
""") """)
@ -414,13 +358,13 @@ class HsOfficeMembershipControllerAcceptanceTest extends ContextBasedTestWithCle
.when() .when()
.patch("http://localhost/api/hs/office/memberships/" + givenMembership.getUuid()) .patch("http://localhost/api/hs/office/memberships/" + givenMembership.getUuid())
.then().assertThat() .then().assertThat()
.statusCode(403); // @formatter:on .statusCode(200); // @formatter:on
// finally, the Membership is actually updated // finally, the Membership is actually updated
assertThat(membershipRepo.findByUuid(givenMembership.getUuid())).isPresent().get() assertThat(membershipRepo.findByUuid(givenMembership.getUuid())).isPresent().get()
.matches(mandate -> { .matches(mandate -> {
assertThat(mandate.getValidity().asString()).isEqualTo("[2022-11-01,)"); assertThat(mandate.getValidity().asString()).isEqualTo("[2022-11-01,2024-01-02)");
assertThat(mandate.getReasonForTermination()).isEqualTo(NONE); assertThat(mandate.getReasonForTermination()).isEqualTo(CANCELLATION);
return true; return true;
}); });
} }
@ -433,7 +377,7 @@ class HsOfficeMembershipControllerAcceptanceTest extends ContextBasedTestWithCle
@Test @Test
void globalAdmin_canDeleteArbitraryMembership() { void globalAdmin_canDeleteArbitraryMembership() {
context.define("superuser-alex@hostsharing.net"); context.define("superuser-alex@hostsharing.net");
final var givenMembership = givenSomeTemporaryMembershipBessler(); final var givenMembership = givenSomeTemporaryMembershipBessler("First");
RestAssured // @formatter:off RestAssured // @formatter:off
.given() .given()
@ -452,12 +396,12 @@ class HsOfficeMembershipControllerAcceptanceTest extends ContextBasedTestWithCle
@Accepts({ "Membership:X(Access Control)" }) @Accepts({ "Membership:X(Access Control)" })
void partnerAgentUser_canNotDeleteRelatedMembership() { void partnerAgentUser_canNotDeleteRelatedMembership() {
context.define("superuser-alex@hostsharing.net"); context.define("superuser-alex@hostsharing.net");
final var givenMembership = givenSomeTemporaryMembershipBessler(); final var givenMembership = givenSomeTemporaryMembershipBessler("First");
RestAssured // @formatter:off RestAssured // @formatter:off
.given() .given()
.header("current-user", "superuser-alex@hostsharing.net") .header("current-user", "superuser-alex@hostsharing.net")
.header("assumed-roles", "hs_office_partner#FirstGmbH-firstcontact.agent") .header("assumed-roles", "hs_office_relationship#HostsharingeG-with-PARTNER-FirstGmbH.agent")
.port(port) .port(port)
.when() .when()
.delete("http://localhost/api/hs/office/memberships/" + givenMembership.getUuid()) .delete("http://localhost/api/hs/office/memberships/" + givenMembership.getUuid())
@ -472,7 +416,7 @@ class HsOfficeMembershipControllerAcceptanceTest extends ContextBasedTestWithCle
@Accepts({ "Membership:X(Access Control)" }) @Accepts({ "Membership:X(Access Control)" })
void normalUser_canNotDeleteUnrelatedMembership() { void normalUser_canNotDeleteUnrelatedMembership() {
context.define("superuser-alex@hostsharing.net"); context.define("superuser-alex@hostsharing.net");
final var givenMembership = givenSomeTemporaryMembershipBessler(); final var givenMembership = givenSomeTemporaryMembershipBessler("First");
RestAssured // @formatter:off RestAssured // @formatter:off
.given() .given()
@ -488,11 +432,10 @@ class HsOfficeMembershipControllerAcceptanceTest extends ContextBasedTestWithCle
} }
} }
private HsOfficeMembershipEntity givenSomeTemporaryMembershipBessler() { private HsOfficeMembershipEntity givenSomeTemporaryMembershipBessler(final String partnerName) {
return jpaAttempt.transacted(() -> { return jpaAttempt.transacted(() -> {
context.define("superuser-alex@hostsharing.net"); context.define("superuser-alex@hostsharing.net");
final var givenDebitor = debitorRepo.findDebitorByOptionalNameLike("First").get(0); final var givenPartner = partnerRepo.findPartnerByOptionalNameLike(partnerName).get(0);
final var givenPartner = partnerRepo.findPartnerByOptionalNameLike("First").get(0);
final var newMembership = HsOfficeMembershipEntity.builder() final var newMembership = HsOfficeMembershipEntity.builder()
.uuid(UUID.randomUUID()) .uuid(UUID.randomUUID())
.partner(givenPartner) .partner(givenPartner)