From 09c19649e448d8a317fd3adfd04540aa4b6b5e79 Mon Sep 17 00:00:00 2001 From: Michael Hoennig Date: Wed, 26 Oct 2022 16:44:51 +0200 Subject: [PATCH] avoid select before insert and map sub-entities in mapper --- .../hsadminng/errors/CustomErrorResponse.java | 6 +- .../RestResponseEntityExceptionHandler.java | 14 +- .../HsOfficeBankAccountController.java | 5 +- .../HsOfficeBankAccountEntity.java | 9 +- .../contact/HsOfficeContactController.java | 3 +- .../office/contact/HsOfficeContactEntity.java | 12 +- ...OfficeCoopAssetsTransactionController.java | 3 +- .../HsOfficeCoopAssetsTransactionEntity.java | 6 +- ...OfficeCoopSharesTransactionController.java | 3 +- .../HsOfficeCoopSharesTransactionEntity.java | 6 +- .../debitor/HsOfficeDebitorController.java | 3 +- .../office/debitor/HsOfficeDebitorEntity.java | 20 +- .../HsOfficeMembershipController.java | 5 +- .../membership/HsOfficeMembershipEntity.java | 21 +- .../partner/HsOfficePartnerController.java | 6 +- .../partner/HsOfficePartnerDetailsEntity.java | 11 +- .../office/partner/HsOfficePartnerEntity.java | 6 +- .../person/HsOfficePersonController.java | 3 +- .../office/person/HsOfficePersonEntity.java | 6 +- .../HsOfficeRelationshipController.java | 3 +- .../HsOfficeRelationshipEntity.java | 6 +- .../HsOfficeSepaMandateController.java | 8 +- .../HsOfficeSepaMandateEntity.java | 6 +- .../hostsharing/hsadminng/mapper/Mapper.java | 49 ++++ .../rbac/rbacrole/RbacRoleEntity.java | 3 + .../rbac/rbacuser/RbacUserEntity.java | 4 + .../test/cust/TestCustomerController.java | 6 +- .../test/cust/TestCustomerEntity.java | 11 +- .../hsadminng/test/pac/TestPackageEntity.java | 6 +- ...esponseEntityExceptionHandlerUnitTest.java | 20 ++ .../bankaccount/TestHsOfficeBankAccount.java | 1 - ...OfficeContactControllerAcceptanceTest.java | 40 ++-- ...fficeContactRepositoryIntegrationTest.java | 3 - .../office/contact/TestHsOfficeContact.java | 1 - ...sTransactionRepositoryIntegrationTest.java | 2 - ...sTransactionRepositoryIntegrationTest.java | 2 - ...OfficeDebitorControllerAcceptanceTest.java | 53 ++--- ...fficeDebitorRepositoryIntegrationTest.java | 3 - .../office/debitor/TestHsOfficeDebitor.java | 1 - .../HsOfficeMembershipControllerRestTest.java | 53 ++++- ...ceMembershipRepositoryIntegrationTest.java | 3 - .../office/membership/TestHsMembership.java | 1 - ...OfficePartnerControllerAcceptanceTest.java | 72 +++--- ...fficePartnerRepositoryIntegrationTest.java | 10 +- .../office/partner/TestHsOfficePartner.java | 1 - ...sOfficePersonControllerAcceptanceTest.java | 110 ++++----- .../hs/office/person/TestHsOfficePerson.java | 1 - ...RelationshipRepositoryIntegrationTest.java | 6 - ...ceSepaMandateControllerAcceptanceTest.java | 63 +++-- ...eSepaMandateRepositoryIntegrationTest.java | 48 ++-- .../rbacrole/RbacRoleControllerRestTest.java | 5 + .../rbacuser/RbacUserControllerRestTest.java | 4 + .../hsadminng/test/cust/TestCustomer.java | 2 +- .../TestCustomerControllerAcceptanceTest.java | 71 +----- ...TestCustomerRepositoryIntegrationTest.java | 2 - .../java/net/hostsharing/test/JpaAttempt.java | 6 + .../net/hostsharing/test/MapperUnitTest.java | 224 ++++++++++++++---- 57 files changed, 621 insertions(+), 437 deletions(-) diff --git a/src/main/java/net/hostsharing/hsadminng/errors/CustomErrorResponse.java b/src/main/java/net/hostsharing/hsadminng/errors/CustomErrorResponse.java index be8bbe65..97fc6ca0 100644 --- a/src/main/java/net/hostsharing/hsadminng/errors/CustomErrorResponse.java +++ b/src/main/java/net/hostsharing/hsadminng/errors/CustomErrorResponse.java @@ -21,13 +21,13 @@ class CustomErrorResponse { static String firstMessageLine(final Throwable exception) { if (exception.getMessage() != null) { - return firstLine(exception.getMessage()); + return line(exception.getMessage(), 0); } return "ERROR: [500] " + exception.getClass().getName(); } - static String firstLine(final String message) { - return message.split("\\r|\\n|\\r\\n", 0)[0]; + static String line(final String message, final int lineNo) { + return message.split("\\r|\\n|\\r\\n", 0)[lineNo]; } @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd hh:mm:ss") diff --git a/src/main/java/net/hostsharing/hsadminng/errors/RestResponseEntityExceptionHandler.java b/src/main/java/net/hostsharing/hsadminng/errors/RestResponseEntityExceptionHandler.java index 0d181752..15cb817c 100644 --- a/src/main/java/net/hostsharing/hsadminng/errors/RestResponseEntityExceptionHandler.java +++ b/src/main/java/net/hostsharing/hsadminng/errors/RestResponseEntityExceptionHandler.java @@ -31,21 +31,25 @@ public class RestResponseEntityExceptionHandler protected ResponseEntity handleConflict( final RuntimeException exc, final WebRequest request) { - final var message = firstLine(NestedExceptionUtils.getMostSpecificCause(exc).getMessage()); + final var rawMessage = NestedExceptionUtils.getMostSpecificCause(exc).getMessage(); + var message = line(rawMessage, 0); + if (message.contains("violates foreign key constraint")) { + return errorResponse(request, HttpStatus.BAD_REQUEST, line(rawMessage, 1).replaceAll(" *Detail: *", "")); + } return errorResponse(request, HttpStatus.CONFLICT, message); } @ExceptionHandler(JpaSystemException.class) protected ResponseEntity handleJpaExceptions( final RuntimeException exc, final WebRequest request) { - final var message = firstLine(NestedExceptionUtils.getMostSpecificCause(exc).getMessage()); + final var message = line(NestedExceptionUtils.getMostSpecificCause(exc).getMessage(), 0); return errorResponse(request, httpStatus(message).orElse(HttpStatus.INTERNAL_SERVER_ERROR), message); } @ExceptionHandler(NoSuchElementException.class) protected ResponseEntity handleNoSuchElementException( final RuntimeException exc, final WebRequest request) { - final var message = firstLine(NestedExceptionUtils.getMostSpecificCause(exc).getMessage()); + final var message = line(NestedExceptionUtils.getMostSpecificCause(exc).getMessage(), 0); return errorResponse(request, HttpStatus.NOT_FOUND, message); } @@ -54,14 +58,14 @@ public class RestResponseEntityExceptionHandler final RuntimeException exc, final WebRequest request) { final var message = userReadableEntityClassName( - firstLine(NestedExceptionUtils.getMostSpecificCause(exc).getMessage())); + line(NestedExceptionUtils.getMostSpecificCause(exc).getMessage(), 0)); return errorResponse(request, HttpStatus.BAD_REQUEST, message); } @ExceptionHandler({ Iban4jException.class, ValidationException.class }) protected ResponseEntity handleIbanAndBicExceptions( final Throwable exc, final WebRequest request) { - final var message = firstLine(NestedExceptionUtils.getMostSpecificCause(exc).getMessage()); + final var message = line(NestedExceptionUtils.getMostSpecificCause(exc).getMessage(), 0); return errorResponse(request, HttpStatus.BAD_REQUEST, message); } diff --git a/src/main/java/net/hostsharing/hsadminng/hs/office/bankaccount/HsOfficeBankAccountController.java b/src/main/java/net/hostsharing/hsadminng/hs/office/bankaccount/HsOfficeBankAccountController.java index 1195b65b..bc6acfa8 100644 --- a/src/main/java/net/hostsharing/hsadminng/hs/office/bankaccount/HsOfficeBankAccountController.java +++ b/src/main/java/net/hostsharing/hsadminng/hs/office/bankaccount/HsOfficeBankAccountController.java @@ -56,14 +56,13 @@ public class HsOfficeBankAccountController implements HsOfficeBankAccountsApi { BicUtil.validate(body.getBic()); final var entityToSave = mapper.map(body, HsOfficeBankAccountEntity.class); - entityToSave.setUuid(UUID.randomUUID()); final var saved = bankAccountRepo.save(entityToSave); final var uri = MvcUriComponentsBuilder.fromController(getClass()) - .path("/api/hs/office/BankAccounts/{id}") - .buildAndExpand(entityToSave.getUuid()) + .path("/api/hs/office/bankaccounts/{id}") + .buildAndExpand(saved.getUuid()) .toUri(); final var mapped = mapper.map(saved, HsOfficeBankAccountResource.class); return ResponseEntity.created(uri).body(mapped); diff --git a/src/main/java/net/hostsharing/hsadminng/hs/office/bankaccount/HsOfficeBankAccountEntity.java b/src/main/java/net/hostsharing/hsadminng/hs/office/bankaccount/HsOfficeBankAccountEntity.java index eb501265..27d49a6e 100644 --- a/src/main/java/net/hostsharing/hsadminng/hs/office/bankaccount/HsOfficeBankAccountEntity.java +++ b/src/main/java/net/hostsharing/hsadminng/hs/office/bankaccount/HsOfficeBankAccountEntity.java @@ -2,11 +2,13 @@ package net.hostsharing.hsadminng.hs.office.bankaccount; import lombok.*; import lombok.experimental.FieldNameConstants; +import net.hostsharing.hsadminng.errors.DisplayName; import net.hostsharing.hsadminng.stringify.Stringify; import net.hostsharing.hsadminng.stringify.Stringifyable; -import net.hostsharing.hsadminng.errors.DisplayName; +import org.hibernate.annotations.GenericGenerator; import javax.persistence.Entity; +import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.Table; import java.util.UUID; @@ -29,7 +31,10 @@ public class HsOfficeBankAccountEntity implements Stringifyable { .withProp(Fields.iban, HsOfficeBankAccountEntity::getIban) .withProp(Fields.bic, HsOfficeBankAccountEntity::getBic); - private @Id UUID uuid; + @Id + @GeneratedValue(generator = "UUID") + @GenericGenerator(name = "UUID", strategy = "org.hibernate.id.UUIDGenerator") + private UUID uuid; private String holder; private String iban; diff --git a/src/main/java/net/hostsharing/hsadminng/hs/office/contact/HsOfficeContactController.java b/src/main/java/net/hostsharing/hsadminng/hs/office/contact/HsOfficeContactController.java index aee1fbd9..073587f2 100644 --- a/src/main/java/net/hostsharing/hsadminng/hs/office/contact/HsOfficeContactController.java +++ b/src/main/java/net/hostsharing/hsadminng/hs/office/contact/HsOfficeContactController.java @@ -52,14 +52,13 @@ public class HsOfficeContactController implements HsOfficeContactsApi { context.define(currentUser, assumedRoles); final var entityToSave = mapper.map(body, HsOfficeContactEntity.class); - entityToSave.setUuid(UUID.randomUUID()); final var saved = contactRepo.save(entityToSave); final var uri = MvcUriComponentsBuilder.fromController(getClass()) .path("/api/hs/office/contacts/{id}") - .buildAndExpand(entityToSave.getUuid()) + .buildAndExpand(saved.getUuid()) .toUri(); final var mapped = mapper.map(saved, HsOfficeContactResource.class); return ResponseEntity.created(uri).body(mapped); diff --git a/src/main/java/net/hostsharing/hsadminng/hs/office/contact/HsOfficeContactEntity.java b/src/main/java/net/hostsharing/hsadminng/hs/office/contact/HsOfficeContactEntity.java index 5a1463af..a8787b6b 100644 --- a/src/main/java/net/hostsharing/hsadminng/hs/office/contact/HsOfficeContactEntity.java +++ b/src/main/java/net/hostsharing/hsadminng/hs/office/contact/HsOfficeContactEntity.java @@ -5,11 +5,9 @@ import lombok.experimental.FieldNameConstants; import net.hostsharing.hsadminng.errors.DisplayName; import net.hostsharing.hsadminng.stringify.Stringify; import net.hostsharing.hsadminng.stringify.Stringifyable; +import org.hibernate.annotations.GenericGenerator; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.Id; -import javax.persistence.Table; +import javax.persistence.*; import java.util.UUID; import static net.hostsharing.hsadminng.stringify.Stringify.stringify; @@ -29,7 +27,11 @@ public class HsOfficeContactEntity implements Stringifyable { .withProp(Fields.label, HsOfficeContactEntity::getLabel) .withProp(Fields.emailAddresses, HsOfficeContactEntity::getEmailAddresses); - private @Id UUID uuid; + + @Id + @GeneratedValue(generator = "UUID") + @GenericGenerator(name = "UUID", strategy = "org.hibernate.id.UUIDGenerator") + private UUID uuid; private String label; @Column(name = "postaladdress") diff --git a/src/main/java/net/hostsharing/hsadminng/hs/office/coopassets/HsOfficeCoopAssetsTransactionController.java b/src/main/java/net/hostsharing/hsadminng/hs/office/coopassets/HsOfficeCoopAssetsTransactionController.java index c794e1fd..fdafbbf8 100644 --- a/src/main/java/net/hostsharing/hsadminng/hs/office/coopassets/HsOfficeCoopAssetsTransactionController.java +++ b/src/main/java/net/hostsharing/hsadminng/hs/office/coopassets/HsOfficeCoopAssetsTransactionController.java @@ -66,14 +66,13 @@ public class HsOfficeCoopAssetsTransactionController implements HsOfficeCoopAsse validate(requestBody); final var entityToSave = mapper.map(requestBody, HsOfficeCoopAssetsTransactionEntity.class); - entityToSave.setUuid(UUID.randomUUID()); final var saved = coopAssetsTransactionRepo.save(entityToSave); final var uri = MvcUriComponentsBuilder.fromController(getClass()) .path("/api/hs/office/coopassetstransactions/{id}") - .buildAndExpand(entityToSave.getUuid()) + .buildAndExpand(saved.getUuid()) .toUri(); final var mapped = mapper.map(saved, HsOfficeCoopAssetsTransactionResource.class); return ResponseEntity.created(uri).body(mapped); diff --git a/src/main/java/net/hostsharing/hsadminng/hs/office/coopassets/HsOfficeCoopAssetsTransactionEntity.java b/src/main/java/net/hostsharing/hsadminng/hs/office/coopassets/HsOfficeCoopAssetsTransactionEntity.java index baf27c76..9a0efe7d 100644 --- a/src/main/java/net/hostsharing/hsadminng/hs/office/coopassets/HsOfficeCoopAssetsTransactionEntity.java +++ b/src/main/java/net/hostsharing/hsadminng/hs/office/coopassets/HsOfficeCoopAssetsTransactionEntity.java @@ -6,6 +6,7 @@ import net.hostsharing.hsadminng.errors.DisplayName; import net.hostsharing.hsadminng.hs.office.membership.HsOfficeMembershipEntity; import net.hostsharing.hsadminng.stringify.Stringify; import net.hostsharing.hsadminng.stringify.Stringifyable; +import org.hibernate.annotations.GenericGenerator; import org.hibernate.annotations.Type; import org.hibernate.annotations.TypeDef; @@ -40,7 +41,10 @@ public class HsOfficeCoopAssetsTransactionEntity implements Stringifyable { .withSeparator(", ") .quotedValues(false); - private @Id UUID uuid; + @Id + @GeneratedValue(generator = "UUID") + @GenericGenerator(name = "UUID", strategy = "org.hibernate.id.UUIDGenerator") + private UUID uuid; @ManyToOne @JoinColumn(name = "membershipuuid") diff --git a/src/main/java/net/hostsharing/hsadminng/hs/office/coopshares/HsOfficeCoopSharesTransactionController.java b/src/main/java/net/hostsharing/hsadminng/hs/office/coopshares/HsOfficeCoopSharesTransactionController.java index 783557f5..7b425acc 100644 --- a/src/main/java/net/hostsharing/hsadminng/hs/office/coopshares/HsOfficeCoopSharesTransactionController.java +++ b/src/main/java/net/hostsharing/hsadminng/hs/office/coopshares/HsOfficeCoopSharesTransactionController.java @@ -67,14 +67,13 @@ public class HsOfficeCoopSharesTransactionController implements HsOfficeCoopShar validate(requestBody); final var entityToSave = mapper.map(requestBody, HsOfficeCoopSharesTransactionEntity.class); - entityToSave.setUuid(UUID.randomUUID()); final var saved = coopSharesTransactionRepo.save(entityToSave); final var uri = MvcUriComponentsBuilder.fromController(getClass()) .path("/api/hs/office/coopsharestransactions/{id}") - .buildAndExpand(entityToSave.getUuid()) + .buildAndExpand(saved.getUuid()) .toUri(); final var mapped = mapper.map(saved, HsOfficeCoopSharesTransactionResource.class); return ResponseEntity.created(uri).body(mapped); diff --git a/src/main/java/net/hostsharing/hsadminng/hs/office/coopshares/HsOfficeCoopSharesTransactionEntity.java b/src/main/java/net/hostsharing/hsadminng/hs/office/coopshares/HsOfficeCoopSharesTransactionEntity.java index c9c58d0b..b4d53ee3 100644 --- a/src/main/java/net/hostsharing/hsadminng/hs/office/coopshares/HsOfficeCoopSharesTransactionEntity.java +++ b/src/main/java/net/hostsharing/hsadminng/hs/office/coopshares/HsOfficeCoopSharesTransactionEntity.java @@ -6,6 +6,7 @@ import net.hostsharing.hsadminng.stringify.Stringify; import net.hostsharing.hsadminng.stringify.Stringifyable; import net.hostsharing.hsadminng.errors.DisplayName; import net.hostsharing.hsadminng.hs.office.membership.HsOfficeMembershipEntity; +import org.hibernate.annotations.GenericGenerator; import org.hibernate.annotations.Type; import org.hibernate.annotations.TypeDef; @@ -38,7 +39,10 @@ public class HsOfficeCoopSharesTransactionEntity implements Stringifyable { .withSeparator(", ") .quotedValues(false); - private @Id UUID uuid; + @Id + @GeneratedValue(generator = "UUID") + @GenericGenerator(name = "UUID", strategy = "org.hibernate.id.UUIDGenerator") + private UUID uuid; @ManyToOne @JoinColumn(name = "membershipuuid") diff --git a/src/main/java/net/hostsharing/hsadminng/hs/office/debitor/HsOfficeDebitorController.java b/src/main/java/net/hostsharing/hsadminng/hs/office/debitor/HsOfficeDebitorController.java index c522387e..c2f80e61 100644 --- a/src/main/java/net/hostsharing/hsadminng/hs/office/debitor/HsOfficeDebitorController.java +++ b/src/main/java/net/hostsharing/hsadminng/hs/office/debitor/HsOfficeDebitorController.java @@ -59,14 +59,13 @@ public class HsOfficeDebitorController implements HsOfficeDebitorsApi { context.define(currentUser, assumedRoles); final var entityToSave = mapper.map(body, HsOfficeDebitorEntity.class); - entityToSave.setUuid(UUID.randomUUID()); final var saved = debitorRepo.save(entityToSave); final var uri = MvcUriComponentsBuilder.fromController(getClass()) .path("/api/hs/office/debitors/{id}") - .buildAndExpand(entityToSave.getUuid()) + .buildAndExpand(saved.getUuid()) .toUri(); final var mapped = mapper.map(saved, HsOfficeDebitorResource.class); return ResponseEntity.created(uri).body(mapped); diff --git a/src/main/java/net/hostsharing/hsadminng/hs/office/debitor/HsOfficeDebitorEntity.java b/src/main/java/net/hostsharing/hsadminng/hs/office/debitor/HsOfficeDebitorEntity.java index 3945c79d..22d9e4aa 100644 --- a/src/main/java/net/hostsharing/hsadminng/hs/office/debitor/HsOfficeDebitorEntity.java +++ b/src/main/java/net/hostsharing/hsadminng/hs/office/debitor/HsOfficeDebitorEntity.java @@ -7,6 +7,7 @@ import net.hostsharing.hsadminng.stringify.Stringifyable; import net.hostsharing.hsadminng.hs.office.bankaccount.HsOfficeBankAccountEntity; import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactEntity; import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerEntity; +import org.hibernate.annotations.GenericGenerator; import javax.persistence.*; import java.util.UUID; @@ -30,28 +31,35 @@ public class HsOfficeDebitorEntity implements Stringifyable { .withSeparator(": ") .quotedValues(false); - private @Id UUID uuid; + @Id + @GeneratedValue(generator = "UUID") + @GenericGenerator(name = "UUID", strategy = "org.hibernate.id.UUIDGenerator") + private UUID uuid; @ManyToOne @JoinColumn(name = "partneruuid") private HsOfficePartnerEntity partner; - private @Column(name = "debitornumber") Integer debitorNumber; + @Column(name = "debitornumber") + private Integer debitorNumber; @ManyToOne @JoinColumn(name = "billingcontactuuid") private HsOfficeContactEntity billingContact; - private @Column(name = "vatid") String vatId; - private @Column(name = "vatcountrycode") String vatCountryCode; - private @Column(name = "vatbusiness") boolean vatBusiness; + @Column(name = "vatid") + private String vatId; + @Column(name = "vatcountrycode") + private String vatCountryCode; + + @Column(name = "vatbusiness") + private boolean vatBusiness; @ManyToOne @JoinColumn(name = "refundbankaccountuuid") private HsOfficeBankAccountEntity refundBankAccount; - @Override public String toString() { return stringify.apply(this); diff --git a/src/main/java/net/hostsharing/hsadminng/hs/office/membership/HsOfficeMembershipController.java b/src/main/java/net/hostsharing/hsadminng/hs/office/membership/HsOfficeMembershipController.java index 4b311706..3e9c4c22 100644 --- a/src/main/java/net/hostsharing/hsadminng/hs/office/membership/HsOfficeMembershipController.java +++ b/src/main/java/net/hostsharing/hsadminng/hs/office/membership/HsOfficeMembershipController.java @@ -61,14 +61,13 @@ public class HsOfficeMembershipController implements HsOfficeMembershipsApi { context.define(currentUser, assumedRoles); final var entityToSave = mapper.map(body, HsOfficeMembershipEntity.class); - entityToSave.setUuid(UUID.randomUUID()); final var saved = membershipRepo.save(entityToSave); final var uri = MvcUriComponentsBuilder.fromController(getClass()) - .path("/api/hs/office/Memberships/{id}") - .buildAndExpand(entityToSave.getUuid()) + .path("/api/hs/office/memberships/{id}") + .buildAndExpand(saved.getUuid()) .toUri(); final var mapped = mapper.map(saved, HsOfficeMembershipResource.class, SEPA_MANDATE_ENTITY_TO_RESOURCE_POSTMAPPER); diff --git a/src/main/java/net/hostsharing/hsadminng/hs/office/membership/HsOfficeMembershipEntity.java b/src/main/java/net/hostsharing/hsadminng/hs/office/membership/HsOfficeMembershipEntity.java index 7e54291c..ce26e843 100644 --- a/src/main/java/net/hostsharing/hsadminng/hs/office/membership/HsOfficeMembershipEntity.java +++ b/src/main/java/net/hostsharing/hsadminng/hs/office/membership/HsOfficeMembershipEntity.java @@ -9,12 +9,11 @@ import net.hostsharing.hsadminng.hs.office.debitor.HsOfficeDebitorEntity; import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerEntity; import net.hostsharing.hsadminng.stringify.Stringify; import net.hostsharing.hsadminng.stringify.Stringifyable; -import org.hibernate.annotations.Fetch; -import org.hibernate.annotations.FetchMode; -import org.hibernate.annotations.Type; -import org.hibernate.annotations.TypeDef; +import org.hibernate.annotations.*; import javax.persistence.*; +import javax.persistence.Entity; +import javax.persistence.Table; import java.time.LocalDate; import java.util.UUID; @@ -48,7 +47,10 @@ public class HsOfficeMembershipEntity implements Stringifyable { .withSeparator(", ") .quotedValues(false); - private @Id UUID uuid; + @Id + @GeneratedValue(generator = "UUID") + @GenericGenerator(name = "UUID", strategy = "org.hibernate.id.UUIDGenerator") + private UUID uuid; @ManyToOne @JoinColumn(name = "partneruuid") @@ -63,7 +65,7 @@ public class HsOfficeMembershipEntity implements Stringifyable { private int memberNumber; @Column(name = "validity", columnDefinition = "daterange") - private Range validity = Range.infinite(LocalDate.class); + private Range validity; @Column(name = "reasonfortermination") @Enumerated(EnumType.STRING) @@ -78,6 +80,13 @@ public class HsOfficeMembershipEntity implements Stringifyable { validity = toPostgresDateRange(getValidity().lower(), validTo); } + public Range getValidity() { + if ( validity == null ) { + validity = Range.infinite(LocalDate.class); + }; + return validity; + } + @Override public String toString() { return stringify.apply(this); diff --git a/src/main/java/net/hostsharing/hsadminng/hs/office/partner/HsOfficePartnerController.java b/src/main/java/net/hostsharing/hsadminng/hs/office/partner/HsOfficePartnerController.java index a5eb62f3..a5a82da2 100644 --- a/src/main/java/net/hostsharing/hsadminng/hs/office/partner/HsOfficePartnerController.java +++ b/src/main/java/net/hostsharing/hsadminng/hs/office/partner/HsOfficePartnerController.java @@ -1,6 +1,7 @@ package net.hostsharing.hsadminng.hs.office.partner; import net.hostsharing.hsadminng.context.Context; +import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactEntity; import net.hostsharing.hsadminng.hs.office.generated.api.v1.api.HsOfficePartnersApi; import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficePartnerInsertResource; import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficePartnerPatchResource; @@ -56,16 +57,13 @@ public class HsOfficePartnerController implements HsOfficePartnersApi { context.define(currentUser, assumedRoles); final var entityToSave = mapper.map(body, HsOfficePartnerEntity.class); - entityToSave.setUuid(UUID.randomUUID()); - entityToSave.setDetails(mapper.map(body.getDetails(), HsOfficePartnerDetailsEntity.class)); - entityToSave.getDetails().setUuid(UUID.randomUUID()); final var saved = partnerRepo.save(entityToSave); final var uri = MvcUriComponentsBuilder.fromController(getClass()) .path("/api/hs/office/partners/{id}") - .buildAndExpand(entityToSave.getUuid()) + .buildAndExpand(saved.getUuid()) .toUri(); final var mapped = mapper.map(saved, HsOfficePartnerResource.class); return ResponseEntity.created(uri).body(mapped); diff --git a/src/main/java/net/hostsharing/hsadminng/hs/office/partner/HsOfficePartnerDetailsEntity.java b/src/main/java/net/hostsharing/hsadminng/hs/office/partner/HsOfficePartnerDetailsEntity.java index 8f03bde4..1e9a0bdd 100644 --- a/src/main/java/net/hostsharing/hsadminng/hs/office/partner/HsOfficePartnerDetailsEntity.java +++ b/src/main/java/net/hostsharing/hsadminng/hs/office/partner/HsOfficePartnerDetailsEntity.java @@ -4,11 +4,9 @@ import lombok.*; import net.hostsharing.hsadminng.stringify.Stringify; import net.hostsharing.hsadminng.stringify.Stringifyable; import net.hostsharing.hsadminng.errors.DisplayName; +import org.hibernate.annotations.GenericGenerator; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.Id; -import javax.persistence.Table; +import javax.persistence.*; import java.time.LocalDate; import java.util.UUID; @@ -35,7 +33,10 @@ public class HsOfficePartnerDetailsEntity implements Stringifyable { .withSeparator(", ") .quotedValues(false); - private @Id UUID uuid; + @Id + @GeneratedValue(generator = "UUID") + @GenericGenerator(name = "UUID", strategy = "org.hibernate.id.UUIDGenerator") + private UUID uuid; private @Column(name = "registrationoffice") String registrationOffice; private @Column(name = "registrationnumber") String registrationNumber; diff --git a/src/main/java/net/hostsharing/hsadminng/hs/office/partner/HsOfficePartnerEntity.java b/src/main/java/net/hostsharing/hsadminng/hs/office/partner/HsOfficePartnerEntity.java index a63d34c0..1c2372b5 100644 --- a/src/main/java/net/hostsharing/hsadminng/hs/office/partner/HsOfficePartnerEntity.java +++ b/src/main/java/net/hostsharing/hsadminng/hs/office/partner/HsOfficePartnerEntity.java @@ -6,6 +6,7 @@ import net.hostsharing.hsadminng.stringify.Stringify; import net.hostsharing.hsadminng.stringify.Stringifyable; import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactEntity; import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonEntity; +import org.hibernate.annotations.GenericGenerator; import org.hibernate.annotations.NotFound; import org.hibernate.annotations.NotFoundAction; @@ -30,7 +31,10 @@ public class HsOfficePartnerEntity implements Stringifyable { .withSeparator(": ") .quotedValues(false); - private @Id UUID uuid; + @Id + @GeneratedValue(generator = "UUID") + @GenericGenerator(name = "UUID", strategy = "org.hibernate.id.UUIDGenerator") + private UUID uuid; @ManyToOne @JoinColumn(name = "personuuid", nullable = false) diff --git a/src/main/java/net/hostsharing/hsadminng/hs/office/person/HsOfficePersonController.java b/src/main/java/net/hostsharing/hsadminng/hs/office/person/HsOfficePersonController.java index 8c0fccb1..409ef07d 100644 --- a/src/main/java/net/hostsharing/hsadminng/hs/office/person/HsOfficePersonController.java +++ b/src/main/java/net/hostsharing/hsadminng/hs/office/person/HsOfficePersonController.java @@ -52,14 +52,13 @@ public class HsOfficePersonController implements HsOfficePersonsApi { context.define(currentUser, assumedRoles); final var entityToSave = mapper.map(body, HsOfficePersonEntity.class); - entityToSave.setUuid(UUID.randomUUID()); final var saved = personRepo.save(entityToSave); final var uri = MvcUriComponentsBuilder.fromController(getClass()) .path("/api/hs/office/persons/{id}") - .buildAndExpand(entityToSave.getUuid()) + .buildAndExpand(saved.getUuid()) .toUri(); final var mapped = mapper.map(saved, HsOfficePersonResource.class); return ResponseEntity.created(uri).body(mapped); diff --git a/src/main/java/net/hostsharing/hsadminng/hs/office/person/HsOfficePersonEntity.java b/src/main/java/net/hostsharing/hsadminng/hs/office/person/HsOfficePersonEntity.java index 3a7a494f..5bcda8c3 100644 --- a/src/main/java/net/hostsharing/hsadminng/hs/office/person/HsOfficePersonEntity.java +++ b/src/main/java/net/hostsharing/hsadminng/hs/office/person/HsOfficePersonEntity.java @@ -7,6 +7,7 @@ import net.hostsharing.hsadminng.errors.DisplayName; import net.hostsharing.hsadminng.stringify.Stringify; import net.hostsharing.hsadminng.stringify.Stringifyable; import org.apache.commons.lang3.StringUtils; +import org.hibernate.annotations.GenericGenerator; import org.hibernate.annotations.Type; import org.hibernate.annotations.TypeDef; @@ -36,7 +37,10 @@ public class HsOfficePersonEntity implements Stringifyable { .withProp(Fields.familyName, HsOfficePersonEntity::getFamilyName) .withProp(Fields.givenName, HsOfficePersonEntity::getGivenName); - private @Id UUID uuid; + @Id + @GeneratedValue(generator = "UUID") + @GenericGenerator(name = "UUID", strategy = "org.hibernate.id.UUIDGenerator") + private UUID uuid; @Column(name = "persontype") @Enumerated(EnumType.STRING) diff --git a/src/main/java/net/hostsharing/hsadminng/hs/office/relationship/HsOfficeRelationshipController.java b/src/main/java/net/hostsharing/hsadminng/hs/office/relationship/HsOfficeRelationshipController.java index d6f36c31..41855c84 100644 --- a/src/main/java/net/hostsharing/hsadminng/hs/office/relationship/HsOfficeRelationshipController.java +++ b/src/main/java/net/hostsharing/hsadminng/hs/office/relationship/HsOfficeRelationshipController.java @@ -69,7 +69,6 @@ public class HsOfficeRelationshipController implements HsOfficeRelationshipsApi final var entityToSave = new HsOfficeRelationshipEntity(); entityToSave.setRelType(HsOfficeRelationshipType.valueOf(body.getRelType())); - entityToSave.setUuid(UUID.randomUUID()); entityToSave.setRelAnchor(relHolderRepo.findByUuid(body.getRelAnchorUuid()).orElseThrow( () -> new NoSuchElementException("cannot find relAnchorUuid " + body.getRelAnchorUuid()) )); @@ -85,7 +84,7 @@ public class HsOfficeRelationshipController implements HsOfficeRelationshipsApi final var uri = MvcUriComponentsBuilder.fromController(getClass()) .path("/api/hs/office/relationships/{id}") - .buildAndExpand(entityToSave.getUuid()) + .buildAndExpand(saved.getUuid()) .toUri(); final var mapped = mapper.map(saved, HsOfficeRelationshipResource.class, RELATIONSHIP_ENTITY_TO_RESOURCE_POSTMAPPER); diff --git a/src/main/java/net/hostsharing/hsadminng/hs/office/relationship/HsOfficeRelationshipEntity.java b/src/main/java/net/hostsharing/hsadminng/hs/office/relationship/HsOfficeRelationshipEntity.java index 39f7997b..71bebadd 100644 --- a/src/main/java/net/hostsharing/hsadminng/hs/office/relationship/HsOfficeRelationshipEntity.java +++ b/src/main/java/net/hostsharing/hsadminng/hs/office/relationship/HsOfficeRelationshipEntity.java @@ -6,6 +6,7 @@ import lombok.experimental.FieldNameConstants; import net.hostsharing.hsadminng.stringify.Stringify; import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactEntity; import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonEntity; +import org.hibernate.annotations.GenericGenerator; import org.hibernate.annotations.Type; import org.hibernate.annotations.TypeDef; @@ -34,7 +35,10 @@ public class HsOfficeRelationshipEntity { .withProp(Fields.relHolder, HsOfficeRelationshipEntity::getRelHolder) .withProp(Fields.contact, HsOfficeRelationshipEntity::getContact); - private @Id UUID uuid; + @Id + @GeneratedValue(generator = "UUID") + @GenericGenerator(name = "UUID", strategy = "org.hibernate.id.UUIDGenerator") + private UUID uuid; @ManyToOne @JoinColumn(name = "relanchoruuid") diff --git a/src/main/java/net/hostsharing/hsadminng/hs/office/sepamandate/HsOfficeSepaMandateController.java b/src/main/java/net/hostsharing/hsadminng/hs/office/sepamandate/HsOfficeSepaMandateController.java index 836ea4a5..fc5124ec 100644 --- a/src/main/java/net/hostsharing/hsadminng/hs/office/sepamandate/HsOfficeSepaMandateController.java +++ b/src/main/java/net/hostsharing/hsadminng/hs/office/sepamandate/HsOfficeSepaMandateController.java @@ -1,12 +1,11 @@ package net.hostsharing.hsadminng.hs.office.sepamandate; -import com.vladmihalcea.hibernate.type.range.Range; -import net.hostsharing.hsadminng.mapper.Mapper; import net.hostsharing.hsadminng.context.Context; import net.hostsharing.hsadminng.hs.office.generated.api.v1.api.HsOfficeSepaMandatesApi; import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeSepaMandateInsertResource; import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeSepaMandatePatchResource; import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeSepaMandateResource; +import net.hostsharing.hsadminng.mapper.Mapper; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.ResponseEntity; import org.springframework.transaction.annotation.Transactional; @@ -62,14 +61,13 @@ public class HsOfficeSepaMandateController implements HsOfficeSepaMandatesApi { context.define(currentUser, assumedRoles); final var entityToSave = mapper.map(body, HsOfficeSepaMandateEntity.class, SEPA_MANDATE_RESOURCE_TO_ENTITY_POSTMAPPER); - entityToSave.setUuid(UUID.randomUUID()); final var saved = SepaMandateRepo.save(entityToSave); final var uri = MvcUriComponentsBuilder.fromController(getClass()) - .path("/api/hs/office/SepaMandates/{id}") - .buildAndExpand(entityToSave.getUuid()) + .path("/api/hs/office/sepamandates/{id}") + .buildAndExpand(saved.getUuid()) .toUri(); final var mapped = mapper.map(saved, HsOfficeSepaMandateResource.class, SEPA_MANDATE_ENTITY_TO_RESOURCE_POSTMAPPER); diff --git a/src/main/java/net/hostsharing/hsadminng/hs/office/sepamandate/HsOfficeSepaMandateEntity.java b/src/main/java/net/hostsharing/hsadminng/hs/office/sepamandate/HsOfficeSepaMandateEntity.java index 15aaf419..84572f2a 100644 --- a/src/main/java/net/hostsharing/hsadminng/hs/office/sepamandate/HsOfficeSepaMandateEntity.java +++ b/src/main/java/net/hostsharing/hsadminng/hs/office/sepamandate/HsOfficeSepaMandateEntity.java @@ -8,6 +8,7 @@ import net.hostsharing.hsadminng.stringify.Stringify; import net.hostsharing.hsadminng.stringify.Stringifyable; import net.hostsharing.hsadminng.hs.office.bankaccount.HsOfficeBankAccountEntity; import net.hostsharing.hsadminng.hs.office.debitor.HsOfficeDebitorEntity; +import org.hibernate.annotations.GenericGenerator; import org.hibernate.annotations.TypeDef; import javax.persistence.*; @@ -37,7 +38,10 @@ public class HsOfficeSepaMandateEntity implements Stringifyable { .withSeparator(", ") .quotedValues(false); - private @Id UUID uuid; + @Id + @GeneratedValue(generator = "UUID") + @GenericGenerator(name = "UUID", strategy = "org.hibernate.id.UUIDGenerator") + private UUID uuid; @ManyToOne @JoinColumn(name = "debitoruuid") diff --git a/src/main/java/net/hostsharing/hsadminng/mapper/Mapper.java b/src/main/java/net/hostsharing/hsadminng/mapper/Mapper.java index e7edacd0..e625a874 100644 --- a/src/main/java/net/hostsharing/hsadminng/mapper/Mapper.java +++ b/src/main/java/net/hostsharing/hsadminng/mapper/Mapper.java @@ -1,7 +1,14 @@ package net.hostsharing.hsadminng.mapper; +import net.hostsharing.hsadminng.errors.DisplayName; import org.modelmapper.ModelMapper; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.util.ReflectionUtils; +import javax.persistence.EntityManager; +import javax.persistence.ManyToOne; +import javax.validation.ValidationException; +import java.lang.reflect.Field; import java.util.List; import java.util.function.BiConsumer; import java.util.stream.Collectors; @@ -11,6 +18,9 @@ import java.util.stream.Collectors; */ public class Mapper extends ModelMapper { + @Autowired + EntityManager em; + public Mapper() { getConfiguration().setAmbiguityIgnored(true); } @@ -32,6 +42,45 @@ public class Mapper extends ModelMapper { .collect(Collectors.toList()); } + @Override + public D map(final Object source, final Class destinationType) { + final var target = super.map(source, destinationType); + for (Field f : destinationType.getDeclaredFields()) { + if (f.getAnnotation(ManyToOne.class) == null) { + continue; + } + ReflectionUtils.makeAccessible(f); + final var subEntity = ReflectionUtils.getField(f, target); + if (subEntity == null) { + continue; + } + final var subEntityUuidField = ReflectionUtils.findField(f.getType(), "uuid"); + if (subEntityUuidField == null) { + continue; + } + ReflectionUtils.makeAccessible(subEntityUuidField); + final var subEntityUuid = ReflectionUtils.getField(subEntityUuidField, subEntity); + if (subEntityUuid == null) { + continue; + } + ReflectionUtils.setField(f, target, findEntityById(f.getType(), subEntityUuid)); + } + return target; + } + + private Object findEntityById(final Class entityClass, final Object subEntityUuid) { + // using getReference would be more efficent, but results in very technical error messages + final var entity = em.find(entityClass, subEntityUuid); + if (entity != null) { + return entity; + } + final var displayNameAnnot = entityClass.getAnnotation(DisplayName.class); + final var displayName = displayNameAnnot != null ? displayNameAnnot.value() : entityClass.getSimpleName(); + throw new ValidationException("Unable to find %s with uuid %s".formatted( + displayName, subEntityUuid + )); + } + public T map(final S source, final Class targetClass, final BiConsumer postMapper) { if (source == null) { return null; diff --git a/src/main/java/net/hostsharing/hsadminng/rbac/rbacrole/RbacRoleEntity.java b/src/main/java/net/hostsharing/hsadminng/rbac/rbacrole/RbacRoleEntity.java index 53264d7a..a4dd3eeb 100644 --- a/src/main/java/net/hostsharing/hsadminng/rbac/rbacrole/RbacRoleEntity.java +++ b/src/main/java/net/hostsharing/hsadminng/rbac/rbacrole/RbacRoleEntity.java @@ -2,6 +2,7 @@ package net.hostsharing.hsadminng.rbac.rbacrole; import lombok.*; import org.hibernate.annotations.Formula; +import org.hibernate.annotations.GenericGenerator; import org.springframework.data.annotation.Immutable; import javax.persistence.*; @@ -18,6 +19,8 @@ import java.util.UUID; public class RbacRoleEntity { @Id + @GeneratedValue(generator = "UUID") + @GenericGenerator(name = "UUID", strategy = "org.hibernate.id.UUIDGenerator") private UUID uuid; @Column(name = "objectuuid") diff --git a/src/main/java/net/hostsharing/hsadminng/rbac/rbacuser/RbacUserEntity.java b/src/main/java/net/hostsharing/hsadminng/rbac/rbacuser/RbacUserEntity.java index 2b936431..82bc6149 100644 --- a/src/main/java/net/hostsharing/hsadminng/rbac/rbacuser/RbacUserEntity.java +++ b/src/main/java/net/hostsharing/hsadminng/rbac/rbacuser/RbacUserEntity.java @@ -1,9 +1,11 @@ package net.hostsharing.hsadminng.rbac.rbacuser; import lombok.*; +import org.hibernate.annotations.GenericGenerator; import org.springframework.data.annotation.Immutable; import javax.persistence.Entity; +import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.Table; import java.time.LocalDateTime; @@ -25,6 +27,8 @@ public class RbacUserEntity { private static DateTimeFormatter DATE_FORMAT_WITH_FULLHOUR = DateTimeFormatter.ofPattern("MM-dd-yyyy HH"); @Id + @GeneratedValue(generator = "UUID") + @GenericGenerator(name = "UUID", strategy = "org.hibernate.id.UUIDGenerator") private UUID uuid; private String name; diff --git a/src/main/java/net/hostsharing/hsadminng/test/cust/TestCustomerController.java b/src/main/java/net/hostsharing/hsadminng/test/cust/TestCustomerController.java index 7123e799..530a7006 100644 --- a/src/main/java/net/hostsharing/hsadminng/test/cust/TestCustomerController.java +++ b/src/main/java/net/hostsharing/hsadminng/test/cust/TestCustomerController.java @@ -48,16 +48,12 @@ public class TestCustomerController implements TestCustomersApi { context.define(currentUser, assumedRoles); - if (customer.getUuid() == null) { - customer.setUuid(UUID.randomUUID()); - } - final var saved = testCustomerRepository.save(mapper.map(customer, TestCustomerEntity.class)); final var uri = MvcUriComponentsBuilder.fromController(getClass()) .path("/api/test/customers/{id}") - .buildAndExpand(customer.getUuid()) + .buildAndExpand(saved.getUuid()) .toUri(); return ResponseEntity.created(uri).body(mapper.map(saved, TestCustomerResource.class)); } diff --git a/src/main/java/net/hostsharing/hsadminng/test/cust/TestCustomerEntity.java b/src/main/java/net/hostsharing/hsadminng/test/cust/TestCustomerEntity.java index d32eaa16..2b985d5b 100644 --- a/src/main/java/net/hostsharing/hsadminng/test/cust/TestCustomerEntity.java +++ b/src/main/java/net/hostsharing/hsadminng/test/cust/TestCustomerEntity.java @@ -4,6 +4,7 @@ import lombok.AllArgsConstructor; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; +import org.hibernate.annotations.GenericGenerator; import javax.persistence.*; import java.util.UUID; @@ -15,8 +16,14 @@ import java.util.UUID; @NoArgsConstructor @AllArgsConstructor public class TestCustomerEntity { - private @Id UUID uuid; + @Id + @GeneratedValue(generator = "UUID") + @GenericGenerator(name = "UUID", strategy = "org.hibernate.id.UUIDGenerator") + private UUID uuid; + private String prefix; private int reference; - private @Column(name="adminusername")String adminUserName; + + @Column(name="adminusername") + private String adminUserName; } diff --git a/src/main/java/net/hostsharing/hsadminng/test/pac/TestPackageEntity.java b/src/main/java/net/hostsharing/hsadminng/test/pac/TestPackageEntity.java index a33ecca3..81b848f1 100644 --- a/src/main/java/net/hostsharing/hsadminng/test/pac/TestPackageEntity.java +++ b/src/main/java/net/hostsharing/hsadminng/test/pac/TestPackageEntity.java @@ -5,6 +5,7 @@ import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; import net.hostsharing.hsadminng.test.cust.TestCustomerEntity; +import org.hibernate.annotations.GenericGenerator; import javax.persistence.*; import java.util.UUID; @@ -17,7 +18,10 @@ import java.util.UUID; @AllArgsConstructor public class TestPackageEntity { - private @Id UUID uuid; + @Id + @GeneratedValue(generator = "UUID") + @GenericGenerator(name = "UUID", strategy = "org.hibernate.id.UUIDGenerator") + private UUID uuid; @Version private int version; diff --git a/src/test/java/net/hostsharing/hsadminng/errors/RestResponseEntityExceptionHandlerUnitTest.java b/src/test/java/net/hostsharing/hsadminng/errors/RestResponseEntityExceptionHandlerUnitTest.java index 27cbfec5..27d738f2 100644 --- a/src/test/java/net/hostsharing/hsadminng/errors/RestResponseEntityExceptionHandlerUnitTest.java +++ b/src/test/java/net/hostsharing/hsadminng/errors/RestResponseEntityExceptionHandlerUnitTest.java @@ -9,6 +9,7 @@ import org.springframework.core.MethodParameter; import org.springframework.dao.DataIntegrityViolationException; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; import org.springframework.orm.jpa.JpaObjectRetrievalFailureException; import org.springframework.orm.jpa.JpaSystemException; import org.springframework.validation.BindingResult; @@ -43,6 +44,25 @@ class RestResponseEntityExceptionHandlerUnitTest { assertThat(errorResponse.getBody().getMessage()).isEqualTo("First Line"); } + @Test + void handleForeignKeyViolation() { + // given + final var givenException = new DataIntegrityViolationException(""" + ... violates foreign key constraint ... + Detail: Second Line + Third Line + """); + final var givenWebRequest = mock(WebRequest.class); + + // when + final var errorResponse = exceptionHandler.handleConflict(givenException, givenWebRequest); + + // then + assertThat(errorResponse.getStatusCodeValue()).isEqualTo(400); + assertThat(errorResponse.getBody()).isNotNull() + .extracting(CustomErrorResponse::getMessage).isEqualTo("Second Line"); + } + @Test void jpaExceptionWithKnownErrorCode() { // given diff --git a/src/test/java/net/hostsharing/hsadminng/hs/office/bankaccount/TestHsOfficeBankAccount.java b/src/test/java/net/hostsharing/hsadminng/hs/office/bankaccount/TestHsOfficeBankAccount.java index 5b5c43ec..7bb7de7e 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/office/bankaccount/TestHsOfficeBankAccount.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/office/bankaccount/TestHsOfficeBankAccount.java @@ -9,7 +9,6 @@ public class TestHsOfficeBankAccount { static public HsOfficeBankAccountEntity hsOfficeBankAccount(final String holder, final String iban, final String bic) { return HsOfficeBankAccountEntity.builder() - .uuid(UUID.randomUUID()) .holder(holder) .iban(iban) .bic(bic) diff --git a/src/test/java/net/hostsharing/hsadminng/hs/office/contact/HsOfficeContactControllerAcceptanceTest.java b/src/test/java/net/hostsharing/hsadminng/hs/office/contact/HsOfficeContactControllerAcceptanceTest.java index 091bd291..f832b245 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/office/contact/HsOfficeContactControllerAcceptanceTest.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/office/contact/HsOfficeContactControllerAcceptanceTest.java @@ -17,8 +17,7 @@ import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.transaction.annotation.Transactional; -import java.util.HashSet; -import java.util.Set; +import javax.persistence.EntityManager; import java.util.UUID; import static net.hostsharing.test.IsValidUuidMatcher.isUuidValid; @@ -49,7 +48,8 @@ class HsOfficeContactControllerAcceptanceTest { @Autowired JpaAttempt jpaAttempt; - Set tempContactUuids = new HashSet<>(); + @Autowired + EntityManager em; @Nested @Accepts({ "Contact:F(Find)" }) @@ -103,7 +103,7 @@ class HsOfficeContactControllerAcceptanceTest { .contentType(ContentType.JSON) .body(""" { - "label": "Test Contact", + "label": "Temp Contact", "emailAddresses": "test@example.org" } """) @@ -114,14 +114,14 @@ class HsOfficeContactControllerAcceptanceTest { .statusCode(201) .contentType(ContentType.JSON) .body("uuid", isUuidValid()) - .body("label", is("Test Contact")) + .body("label", is("Temp Contact")) .body("emailAddresses", is("test@example.org")) .header("Location", startsWith("http://localhost")) .extract().header("Location"); // @formatter:on // finally, the new contact can be accessed under the generated UUID - final var newUserUuid = toCleanup(UUID.fromString( - location.substring(location.lastIndexOf('/') + 1))); + final var newUserUuid = UUID.fromString( + location.substring(location.lastIndexOf('/') + 1)); assertThat(newUserUuid).isNotNull(); } } @@ -208,7 +208,7 @@ class HsOfficeContactControllerAcceptanceTest { .contentType(ContentType.JSON) .body(""" { - "label": "patched contact", + "label": "Temp patched contact", "emailAddresses": "patched@example.org", "postalAddress": "Patched Address", "phoneNumbers": "+01 100 123456" @@ -221,7 +221,7 @@ class HsOfficeContactControllerAcceptanceTest { .statusCode(200) .contentType(ContentType.JSON) .body("uuid", isUuidValid()) - .body("label", is("patched contact")) + .body("label", is("Temp patched contact")) .body("emailAddresses", is("patched@example.org")) .body("postalAddress", is("Patched Address")) .body("phoneNumbers", is("+01 100 123456")); @@ -231,7 +231,7 @@ class HsOfficeContactControllerAcceptanceTest { context.define("superuser-alex@hostsharing.net"); assertThat(contactRepo.findByUuid(givenContact.getUuid())).isPresent().get() .matches(person -> { - assertThat(person.getLabel()).isEqualTo("patched contact"); + assertThat(person.getLabel()).isEqualTo("Temp patched contact"); assertThat(person.getEmailAddresses()).isEqualTo("patched@example.org"); assertThat(person.getPostalAddress()).isEqualTo("Patched Address"); assertThat(person.getPhoneNumbers()).isEqualTo("+01 100 123456"); @@ -353,28 +353,16 @@ class HsOfficeContactControllerAcceptanceTest { .phoneNumbers("+01 200 " + RandomStringUtils.randomNumeric(8)) .build(); - toCleanup(newContact.getUuid()); - return contactRepo.save(newContact); }).assertSuccessful().returnedValue(); } - private UUID toCleanup(final UUID tempContactUuid) { - tempContactUuids.add(tempContactUuid); - return tempContactUuid; - } - @BeforeEach @AfterEach void cleanup() { - tempContactUuids.forEach(uuid -> { - jpaAttempt.transacted(() -> { - context.define("superuser-alex@hostsharing.net", null); - System.out.println("DELETING temporary contact: " + uuid); - final var count = contactRepo.deleteByUuid(uuid); - System.out.println("DELETED temporary contact: " + uuid + (count > 0 ? " successful" : " failed")); - }).assertSuccessful(); - }); + jpaAttempt.transacted(() -> { + context.define("superuser-alex@hostsharing.net", null); + em.createQuery("DELETE FROM HsOfficeContactEntity c WHERE c.label LIKE 'Temp %'").executeUpdate(); + }).assertSuccessful(); } - } diff --git a/src/test/java/net/hostsharing/hsadminng/hs/office/contact/HsOfficeContactRepositoryIntegrationTest.java b/src/test/java/net/hostsharing/hsadminng/hs/office/contact/HsOfficeContactRepositoryIntegrationTest.java index 2079fe7d..2c4bac6e 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/office/contact/HsOfficeContactRepositoryIntegrationTest.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/office/contact/HsOfficeContactRepositoryIntegrationTest.java @@ -54,9 +54,6 @@ class HsOfficeContactRepositoryIntegrationTest extends ContextBasedTest { @MockBean HttpServletRequest request; - @Container - Container postgres; - @Nested class CreateContact { diff --git a/src/test/java/net/hostsharing/hsadminng/hs/office/contact/TestHsOfficeContact.java b/src/test/java/net/hostsharing/hsadminng/hs/office/contact/TestHsOfficeContact.java index 02c33305..58284258 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/office/contact/TestHsOfficeContact.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/office/contact/TestHsOfficeContact.java @@ -8,7 +8,6 @@ public class TestHsOfficeContact { static public HsOfficeContactEntity hsOfficeContact(final String label, final String emailAddr) { return HsOfficeContactEntity.builder() - .uuid(UUID.randomUUID()) .label(label) .postalAddress("address of " + label) .emailAddresses(emailAddr) diff --git a/src/test/java/net/hostsharing/hsadminng/hs/office/coopassets/HsOfficeCoopAssetsTransactionRepositoryIntegrationTest.java b/src/test/java/net/hostsharing/hsadminng/hs/office/coopassets/HsOfficeCoopAssetsTransactionRepositoryIntegrationTest.java index d02176b1..44f5ea6b 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/office/coopassets/HsOfficeCoopAssetsTransactionRepositoryIntegrationTest.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/office/coopassets/HsOfficeCoopAssetsTransactionRepositoryIntegrationTest.java @@ -71,7 +71,6 @@ class HsOfficeCoopAssetsTransactionRepositoryIntegrationTest extends ContextBase // when final var result = attempt(em, () -> { final var newCoopAssetsTransaction = HsOfficeCoopAssetsTransactionEntity.builder() - .uuid(UUID.randomUUID()) .membership(givenMembership) .transactionType(HsOfficeCoopAssetsTransactionType.DEPOSIT) .assetValue(new BigDecimal("128.00")) @@ -104,7 +103,6 @@ class HsOfficeCoopAssetsTransactionRepositoryIntegrationTest extends ContextBase null, 10001).get(0); final var newCoopAssetsTransaction = HsOfficeCoopAssetsTransactionEntity.builder() - .uuid(UUID.randomUUID()) .membership(givenMembership) .transactionType(HsOfficeCoopAssetsTransactionType.DEPOSIT) .assetValue(new BigDecimal("128.00")) diff --git a/src/test/java/net/hostsharing/hsadminng/hs/office/coopshares/HsOfficeCoopSharesTransactionRepositoryIntegrationTest.java b/src/test/java/net/hostsharing/hsadminng/hs/office/coopshares/HsOfficeCoopSharesTransactionRepositoryIntegrationTest.java index 6d653175..87a2f2dc 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/office/coopshares/HsOfficeCoopSharesTransactionRepositoryIntegrationTest.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/office/coopshares/HsOfficeCoopSharesTransactionRepositoryIntegrationTest.java @@ -69,7 +69,6 @@ class HsOfficeCoopSharesTransactionRepositoryIntegrationTest extends ContextBase // when final var result = attempt(em, () -> { final var newCoopSharesTransaction = HsOfficeCoopSharesTransactionEntity.builder() - .uuid(UUID.randomUUID()) .membership(givenMembership) .transactionType(HsOfficeCoopSharesTransactionType.SUBSCRIPTION) .shareCount(4) @@ -102,7 +101,6 @@ class HsOfficeCoopSharesTransactionRepositoryIntegrationTest extends ContextBase null, 10001).get(0); final var newCoopSharesTransaction = HsOfficeCoopSharesTransactionEntity.builder() - .uuid(UUID.randomUUID()) .membership(givenMembership) .transactionType(HsOfficeCoopSharesTransactionType.SUBSCRIPTION) .shareCount(4) diff --git a/src/test/java/net/hostsharing/hsadminng/hs/office/debitor/HsOfficeDebitorControllerAcceptanceTest.java b/src/test/java/net/hostsharing/hsadminng/hs/office/debitor/HsOfficeDebitorControllerAcceptanceTest.java index 79a8128f..2867c6fa 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/office/debitor/HsOfficeDebitorControllerAcceptanceTest.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/office/debitor/HsOfficeDebitorControllerAcceptanceTest.java @@ -2,15 +2,16 @@ package net.hostsharing.hsadminng.hs.office.debitor; import io.restassured.RestAssured; import io.restassured.http.ContentType; -import net.hostsharing.test.Accepts; import net.hostsharing.hsadminng.HsadminNgApplication; import net.hostsharing.hsadminng.context.Context; import net.hostsharing.hsadminng.hs.office.bankaccount.HsOfficeBankAccountRepository; import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactRepository; import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerRepository; +import net.hostsharing.test.Accepts; import net.hostsharing.test.JpaAttempt; import org.json.JSONException; import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; @@ -18,8 +19,7 @@ import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.transaction.annotation.Transactional; -import java.util.HashSet; -import java.util.Set; +import javax.persistence.EntityManager; import java.util.UUID; import static net.hostsharing.test.IsValidUuidMatcher.isUuidValid; @@ -35,7 +35,8 @@ import static org.hamcrest.Matchers.*; @Transactional class HsOfficeDebitorControllerAcceptanceTest { - private static int nextDebitorNumber = 20001; + private static final int LOWEST_TEMP_DEBITOR_NUMBER = 20000; + private static int nextDebitorNumber = LOWEST_TEMP_DEBITOR_NUMBER; @LocalServerPort private Integer port; @@ -58,7 +59,8 @@ class HsOfficeDebitorControllerAcceptanceTest { @Autowired JpaAttempt jpaAttempt; - Set tempDebitorUuids = new HashSet<>(); + @Autowired + EntityManager em; @Nested @Accepts({ "Debitor:F(Find)" }) @@ -164,7 +166,7 @@ class HsOfficeDebitorControllerAcceptanceTest { "vatBusiness": true, "refundBankAccountUuid": "%s" } - """.formatted( givenPartner.getUuid(), givenContact.getUuid(), nextDebitorNumber++, givenBankAccount.getUuid())) + """.formatted( givenPartner.getUuid(), givenContact.getUuid(), ++nextDebitorNumber, givenBankAccount.getUuid())) .port(port) .when() .post("http://localhost/api/hs/office/debitors") @@ -180,8 +182,8 @@ class HsOfficeDebitorControllerAcceptanceTest { .extract().header("Location"); // @formatter:on // finally, the new debitor can be accessed under the generated UUID - final var newUserUuid = toCleanup(UUID.fromString( - location.substring(location.lastIndexOf('/') + 1))); + final var newUserUuid = UUID.fromString( + location.substring(location.lastIndexOf('/') + 1)); assertThat(newUserUuid).isNotNull(); } @@ -202,7 +204,7 @@ class HsOfficeDebitorControllerAcceptanceTest { "billingContactUuid": "%s", "debitorNumber": "%s" } - """.formatted( givenPartner.getUuid(), givenContact.getUuid(), nextDebitorNumber++)) + """.formatted( givenPartner.getUuid(), givenContact.getUuid(), ++nextDebitorNumber)) .port(port) .when() .post("http://localhost/api/hs/office/debitors") @@ -220,8 +222,8 @@ class HsOfficeDebitorControllerAcceptanceTest { .extract().header("Location"); // @formatter:on // finally, the new debitor can be accessed under the generated UUID - final var newUserUuid = toCleanup(UUID.fromString( - location.substring(location.lastIndexOf('/') + 1))); + final var newUserUuid = UUID.fromString( + location.substring(location.lastIndexOf('/') + 1)); assertThat(newUserUuid).isNotNull(); } @@ -245,7 +247,7 @@ class HsOfficeDebitorControllerAcceptanceTest { "vatCountryCode": "DE", "vatBusiness": true } - """.formatted( givenPartner.getUuid(), givenContactUuid, nextDebitorNumber++)) + """.formatted( givenPartner.getUuid(), givenContactUuid, ++nextDebitorNumber)) .port(port) .when() .post("http://localhost/api/hs/office/debitors") @@ -275,7 +277,7 @@ class HsOfficeDebitorControllerAcceptanceTest { "vatCountryCode": "DE", "vatBusiness": true } - """.formatted( givenPartnerUuid, givenContact.getUuid(), nextDebitorNumber++)) + """.formatted( givenPartnerUuid, givenContact.getUuid(), ++nextDebitorNumber)) .port(port) .when() .post("http://localhost/api/hs/office/debitors") @@ -520,33 +522,24 @@ class HsOfficeDebitorControllerAcceptanceTest { final var givenPartner = partnerRepo.findPartnerByOptionalNameLike("Fourth").get(0); final var givenContact = contactRepo.findContactByOptionalLabelLike("forth contact").get(0); final var newDebitor = HsOfficeDebitorEntity.builder() - .uuid(UUID.randomUUID()) - .debitorNumber(nextDebitorNumber++) + .debitorNumber(++nextDebitorNumber) .partner(givenPartner) .billingContact(givenContact) .build(); - toCleanup(newDebitor.getUuid()); - return debitorRepo.save(newDebitor); }).assertSuccessful().returnedValue(); } - private UUID toCleanup(final UUID tempDebitorUuid) { - tempDebitorUuids.add(tempDebitorUuid); - return tempDebitorUuid; - } - + @BeforeEach @AfterEach void cleanup() { - tempDebitorUuids.forEach(uuid -> { - jpaAttempt.transacted(() -> { - context.define("superuser-alex@hostsharing.net", null); - System.out.println("DELETING temporary debitor: " + uuid); - final var count = debitorRepo.deleteByUuid(uuid); - System.out.println("DELETED temporary debitor: " + uuid + (count > 0 ? " successful" : " failed")); - }); + jpaAttempt.transacted(() -> { + context.define("superuser-alex@hostsharing.net"); + final var count = em.createQuery( + "DELETE FROM HsOfficeDebitorEntity d WHERE d.debitorNumber > " + LOWEST_TEMP_DEBITOR_NUMBER) + .executeUpdate(); + System.out.printf("deleted %d entities%n", count); }); } - } diff --git a/src/test/java/net/hostsharing/hsadminng/hs/office/debitor/HsOfficeDebitorRepositoryIntegrationTest.java b/src/test/java/net/hostsharing/hsadminng/hs/office/debitor/HsOfficeDebitorRepositoryIntegrationTest.java index 86ebf4a6..8be99fdc 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/office/debitor/HsOfficeDebitorRepositoryIntegrationTest.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/office/debitor/HsOfficeDebitorRepositoryIntegrationTest.java @@ -79,7 +79,6 @@ class HsOfficeDebitorRepositoryIntegrationTest extends ContextBasedTest { // when final var result = attempt(em, () -> { final var newDebitor = HsOfficeDebitorEntity.builder() - .uuid(UUID.randomUUID()) .debitorNumber(20001) .partner(givenPartner) .billingContact(givenContact) @@ -112,7 +111,6 @@ class HsOfficeDebitorRepositoryIntegrationTest extends ContextBasedTest { final var givenPartner = partnerRepo.findPartnerByOptionalNameLike("Fourth").get(0); final var givenContact = contactRepo.findContactByOptionalLabelLike("forth contact").get(0); final var newDebitor = HsOfficeDebitorEntity.builder() - .uuid(UUID.randomUUID()) .debitorNumber(20002) .partner(givenPartner) .billingContact(givenContact) @@ -544,7 +542,6 @@ class HsOfficeDebitorRepositoryIntegrationTest extends ContextBasedTest { final var givenBankAccount = bankAccount != null ? bankAccountRepo.findByOptionalHolderLike(bankAccount).get(0) : null; final var newDebitor = HsOfficeDebitorEntity.builder() - .uuid(UUID.randomUUID()) .debitorNumber(20000) .partner(givenPartner) .billingContact(givenContact) diff --git a/src/test/java/net/hostsharing/hsadminng/hs/office/debitor/TestHsOfficeDebitor.java b/src/test/java/net/hostsharing/hsadminng/hs/office/debitor/TestHsOfficeDebitor.java index d36524c4..9d2c6b7f 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/office/debitor/TestHsOfficeDebitor.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/office/debitor/TestHsOfficeDebitor.java @@ -11,7 +11,6 @@ import static net.hostsharing.hsadminng.hs.office.partner.TestHsOfficePartner.TE public class TestHsOfficeDebitor { public static final HsOfficeDebitorEntity TEST_DEBITOR = HsOfficeDebitorEntity.builder() - .uuid(UUID.randomUUID()) .debitorNumber(10001) .partner(TEST_PARTNER) .billingContact(TEST_CONTACT) diff --git a/src/test/java/net/hostsharing/hsadminng/hs/office/membership/HsOfficeMembershipControllerRestTest.java b/src/test/java/net/hostsharing/hsadminng/hs/office/membership/HsOfficeMembershipControllerRestTest.java index d30715c3..b948d5f5 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/office/membership/HsOfficeMembershipControllerRestTest.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/office/membership/HsOfficeMembershipControllerRestTest.java @@ -2,26 +2,25 @@ package net.hostsharing.hsadminng.hs.office.membership; import net.hostsharing.hsadminng.context.Context; import net.hostsharing.hsadminng.hs.office.coopassets.HsOfficeCoopAssetsTransactionRepository; +import net.hostsharing.hsadminng.hs.office.debitor.HsOfficeDebitorEntity; +import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerEntity; import net.hostsharing.hsadminng.mapper.Mapper; import org.junit.jupiter.api.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; import org.springframework.boot.test.mock.mockito.MockBean; -import org.springframework.boot.test.mock.mockito.SpyBean; import org.springframework.context.annotation.Import; import org.springframework.http.MediaType; -import org.springframework.orm.jpa.JpaObjectRetrievalFailureException; import org.springframework.test.context.junit4.SpringRunner; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; import javax.persistence.EntityManager; -import javax.persistence.EntityNotFoundException; import java.util.UUID; import static org.hamcrest.Matchers.is; -import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; @@ -97,14 +96,13 @@ public class HsOfficeMembershipControllerRestTest { } @Test - void respondBadRequest_ifAnyGivenUuidCannotBeResolved() throws Exception { + void respondBadRequest_ifAnyGivenPartnerUuidCannotBeFound() throws Exception { // given - when(membershipRepo.save(any())).thenThrow( - new JpaObjectRetrievalFailureException( - new EntityNotFoundException( - // same would happen with HsOfficePartnerEntity which could not be resolved - "Unable to find net.hostsharing.hsadminng.hs.office.debitor.HsOfficeDebitorEntity with id ..."))); + final var givenPartnerUuid = UUID.randomUUID(); + final var givenMainDebitorUuid = UUID.randomUUID(); + when(em.find(HsOfficePartnerEntity.class, givenPartnerUuid)).thenReturn(null); + when(em.find(HsOfficeDebitorEntity.class, givenMainDebitorUuid)).thenReturn(mock(HsOfficeDebitorEntity.class)); // when mockMvc.perform(MockMvcRequestBuilders @@ -118,13 +116,44 @@ public class HsOfficeMembershipControllerRestTest { "memberNumber": 20001, "validFrom": "2022-10-13" } - """.formatted(UUID.randomUUID(), UUID.randomUUID())) + """.formatted(givenPartnerUuid, givenMainDebitorUuid)) .accept(MediaType.APPLICATION_JSON)) // then .andExpect(status().is4xxClientError()) .andExpect(jsonPath("status", is(400))) .andExpect(jsonPath("error", is("Bad Request"))) - .andExpect(jsonPath("message", is("Unable to find Debitor with uuid ..."))); + .andExpect(jsonPath("message", is("Unable to find Partner with uuid " + givenPartnerUuid))); + } + + @Test + void respondBadRequest_ifAnyGivenDebitorUuidCannotBeFound() throws Exception { + + // given + final var givenPartnerUuid = UUID.randomUUID(); + final var givenMainDebitorUuid = UUID.randomUUID(); + when(em.find(HsOfficePartnerEntity.class, givenPartnerUuid)).thenReturn(mock(HsOfficePartnerEntity.class)); + when(em.find(HsOfficeDebitorEntity.class, givenMainDebitorUuid)).thenReturn(null); + + // when + mockMvc.perform(MockMvcRequestBuilders + .post("/api/hs/office/memberships") + .header("current-user", "superuser-alex@hostsharing.net") + .contentType(MediaType.APPLICATION_JSON) + .content(""" + { + "partnerUuid": "%s", + "mainDebitorUuid": "%s", + "memberNumber": 20001, + "validFrom": "2022-10-13" + } + """.formatted(givenPartnerUuid, givenMainDebitorUuid)) + .accept(MediaType.APPLICATION_JSON)) + + // then + .andExpect(status().is4xxClientError()) + .andExpect(jsonPath("status", is(400))) + .andExpect(jsonPath("error", is("Bad Request"))) + .andExpect(jsonPath("message", is("Unable to find Debitor with uuid " + givenMainDebitorUuid))); } } diff --git a/src/test/java/net/hostsharing/hsadminng/hs/office/membership/HsOfficeMembershipRepositoryIntegrationTest.java b/src/test/java/net/hostsharing/hsadminng/hs/office/membership/HsOfficeMembershipRepositoryIntegrationTest.java index 0b3ac4a3..f54d5fa0 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/office/membership/HsOfficeMembershipRepositoryIntegrationTest.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/office/membership/HsOfficeMembershipRepositoryIntegrationTest.java @@ -76,7 +76,6 @@ class HsOfficeMembershipRepositoryIntegrationTest extends ContextBasedTest { // when final var result = attempt(em, () -> { final var newMembership = toCleanup(HsOfficeMembershipEntity.builder() - .uuid(UUID.randomUUID()) .memberNumber(20001) .partner(givenPartner) .mainDebitor(givenDebitor) @@ -107,7 +106,6 @@ class HsOfficeMembershipRepositoryIntegrationTest extends ContextBasedTest { final var givenPartner = partnerRepo.findPartnerByOptionalNameLike("First").get(0); final var givenDebitor = debitorRepo.findDebitorByOptionalNameLike("First").get(0); final var newMembership = toCleanup(HsOfficeMembershipEntity.builder() - .uuid(UUID.randomUUID()) .memberNumber(20002) .partner(givenPartner) .mainDebitor(givenDebitor) @@ -409,7 +407,6 @@ class HsOfficeMembershipRepositoryIntegrationTest extends ContextBasedTest { final var givenPartner = partnerRepo.findPartnerByOptionalNameLike(partnerTradeName).get(0); final var givenDebitor = debitorRepo.findDebitorByOptionalNameLike(debitorName).get(0); final var newMembership = HsOfficeMembershipEntity.builder() - .uuid(UUID.randomUUID()) .memberNumber(20002) .partner(givenPartner) .mainDebitor(givenDebitor) diff --git a/src/test/java/net/hostsharing/hsadminng/hs/office/membership/TestHsMembership.java b/src/test/java/net/hostsharing/hsadminng/hs/office/membership/TestHsMembership.java index 4377eaf8..1b40a4ce 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/office/membership/TestHsMembership.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/office/membership/TestHsMembership.java @@ -11,7 +11,6 @@ public class TestHsMembership { public static final HsOfficeMembershipEntity TEST_MEMBERSHIP = HsOfficeMembershipEntity.builder() - .uuid(UUID.randomUUID()) .partner(TEST_PARTNER) .memberNumber(300001) .validity(Range.closedInfinite(LocalDate.parse("2020-01-01"))) diff --git a/src/test/java/net/hostsharing/hsadminng/hs/office/partner/HsOfficePartnerControllerAcceptanceTest.java b/src/test/java/net/hostsharing/hsadminng/hs/office/partner/HsOfficePartnerControllerAcceptanceTest.java index e25c0fa2..bc1f1e43 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/office/partner/HsOfficePartnerControllerAcceptanceTest.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/office/partner/HsOfficePartnerControllerAcceptanceTest.java @@ -17,8 +17,7 @@ import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.transaction.annotation.Transactional; -import java.util.HashSet; -import java.util.Set; +import javax.persistence.EntityManager; import java.util.UUID; import static net.hostsharing.test.IsValidUuidMatcher.isUuidValid; @@ -32,7 +31,6 @@ import static org.hamcrest.Matchers.startsWith; webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = { HsadminNgApplication.class, JpaAttempt.class } ) -@Transactional class HsOfficePartnerControllerAcceptanceTest { @LocalServerPort @@ -56,10 +54,12 @@ class HsOfficePartnerControllerAcceptanceTest { @Autowired JpaAttempt jpaAttempt; - Set tempPartnerUuids = new HashSet<>(); + @Autowired + EntityManager em; @Nested @Accepts({ "Partner:F(Find)" }) + @Transactional class ListPartners { @Test @@ -109,6 +109,7 @@ class HsOfficePartnerControllerAcceptanceTest { @Nested @Accepts({ "Partner:C(Create)" }) + @Transactional class AddPartner { @Test @@ -127,8 +128,8 @@ class HsOfficePartnerControllerAcceptanceTest { "contactUuid": "%s", "personUuid": "%s", "details": { - "registrationOffice": "Registergericht Aurich", - "registrationNumber": "123456" + "registrationOffice": "Temp Registergericht Aurich", + "registrationNumber": "111111" } } """.formatted(givenContact.getUuid(), givenPerson.getUuid())) @@ -139,16 +140,16 @@ class HsOfficePartnerControllerAcceptanceTest { .statusCode(201) .contentType(ContentType.JSON) .body("uuid", isUuidValid()) - .body("details.registrationOffice", is("Registergericht Aurich")) - .body("details.registrationNumber", is("123456")) + .body("details.registrationOffice", is("Temp Registergericht Aurich")) + .body("details.registrationNumber", is("111111")) .body("contact.label", is(givenContact.getLabel())) .body("person.tradeName", is(givenPerson.getTradeName())) .header("Location", startsWith("http://localhost")) .extract().header("Location"); // @formatter:on // finally, the new partner can be accessed under the generated UUID - final var newUserUuid = toCleanup(UUID.fromString( - location.substring(location.lastIndexOf('/') + 1))); + final var newUserUuid = UUID.fromString( + location.substring(location.lastIndexOf('/') + 1)); assertThat(newUserUuid).isNotNull(); } @@ -209,6 +210,7 @@ class HsOfficePartnerControllerAcceptanceTest { @Nested @Accepts({ "Partner:R(Read)" }) + @Transactional class GetPartner { @Test @@ -275,6 +277,7 @@ class HsOfficePartnerControllerAcceptanceTest { @Nested @Accepts({ "Partner:U(Update)" }) + @Transactional class PatchPartner { @Test @@ -294,7 +297,7 @@ class HsOfficePartnerControllerAcceptanceTest { "contactUuid": "%s", "personUuid": "%s", "details": { - "registrationOffice": "Registergericht Hamburg", + "registrationOffice": "Temp Registergericht Aurich", "registrationNumber": "222222", "birthName": "Maja Schmidt", "birthday": "1938-04-08", @@ -320,7 +323,7 @@ class HsOfficePartnerControllerAcceptanceTest { .matches(person -> { assertThat(person.getPerson().getTradeName()).isEqualTo("Third OHG"); assertThat(person.getContact().getLabel()).isEqualTo("forth contact"); - assertThat(person.getDetails().getRegistrationOffice()).isEqualTo("Registergericht Hamburg"); + assertThat(person.getDetails().getRegistrationOffice()).isEqualTo("Temp Registergericht Aurich"); assertThat(person.getDetails().getRegistrationNumber()).isEqualTo("222222"); assertThat(person.getDetails().getBirthName()).isEqualTo("Maja Schmidt"); assertThat(person.getDetails().getBirthday()).isEqualTo("1938-04-08"); @@ -365,8 +368,8 @@ class HsOfficePartnerControllerAcceptanceTest { .matches(person -> { assertThat(person.getPerson().getTradeName()).isEqualTo(givenPartner.getPerson().getTradeName()); assertThat(person.getContact().getLabel()).isEqualTo(givenPartner.getContact().getLabel()); - assertThat(person.getDetails().getRegistrationOffice()).isEqualTo(null); - assertThat(person.getDetails().getRegistrationNumber()).isEqualTo(null); + assertThat(person.getDetails().getRegistrationOffice()).isEqualTo("Temp Registergericht Leer"); + assertThat(person.getDetails().getRegistrationNumber()).isEqualTo("333333"); assertThat(person.getDetails().getBirthName()).isEqualTo("Maja Schmidt"); assertThat(person.getDetails().getBirthday()).isEqualTo("1938-04-08"); assertThat(person.getDetails().getDateOfDeath()).isEqualTo("2022-01-12"); @@ -378,6 +381,7 @@ class HsOfficePartnerControllerAcceptanceTest { @Nested @Accepts({ "Partner:D(Delete)" }) + @Transactional class DeletePartner { @Test @@ -445,35 +449,41 @@ class HsOfficePartnerControllerAcceptanceTest { final var givenPerson = personRepo.findPersonByOptionalNameLike("Erben Bessler").get(0); final var givenContact = contactRepo.findContactByOptionalLabelLike("forth contact").get(0); final var newPartner = HsOfficePartnerEntity.builder() - .uuid(UUID.randomUUID()) .person(givenPerson) .contact(givenContact) .details(HsOfficePartnerDetailsEntity.builder() - .uuid((UUID.randomUUID())) + .registrationOffice("Temp Registergericht Leer") + .registrationNumber("333333") .build()) .build(); - toCleanup(newPartner.getUuid()); - return partnerRepo.save(newPartner); }).assertSuccessful().returnedValue(); } - private UUID toCleanup(final UUID tempPartnerUuid) { - tempPartnerUuids.add(tempPartnerUuid); - return tempPartnerUuid; - } - @AfterEach void cleanup() { - tempPartnerUuids.forEach(uuid -> { - jpaAttempt.transacted(() -> { - context.define("superuser-alex@hostsharing.net", null); - System.out.println("DELETING temporary partner: " + uuid); - final var count = partnerRepo.deleteByUuid(uuid); - System.out.println("DELETED temporary partner: " + uuid + (count > 0 ? " successful" : " failed")); - }); - }); + final var deleted = jpaAttempt.transacted(() -> { + context.define("superuser-alex@hostsharing.net", null); + em.createNativeQuery(""" + delete from hs_office_partner p + where p.detailsuuid in ( + select d.uuid from hs_office_partner_details d + where d.registrationoffice like 'Temp %') + """) + .executeUpdate(); + }).assertSuccessful().returnedValue(); + + final var remaining = jpaAttempt.transacted(() -> { + em.createNativeQuery(""" + select count(p) from hs_office_partner p + where p.detailsuuid in ( + select d.uuid from hs_office_partner_details d + where d.registrationoffice like 'Temp %') + """) + .getSingleResult(); + }).assertSuccessful().returnedValue(); + System.err.println("@AfterEach" + ": " + deleted + " records deleted, " + remaining + " remaining"); } } diff --git a/src/test/java/net/hostsharing/hsadminng/hs/office/partner/HsOfficePartnerRepositoryIntegrationTest.java b/src/test/java/net/hostsharing/hsadminng/hs/office/partner/HsOfficePartnerRepositoryIntegrationTest.java index 49e5b059..0213c09b 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/office/partner/HsOfficePartnerRepositoryIntegrationTest.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/office/partner/HsOfficePartnerRepositoryIntegrationTest.java @@ -73,11 +73,9 @@ class HsOfficePartnerRepositoryIntegrationTest extends ContextBasedTest { // when final var result = attempt(em, () -> { final var newPartner = toCleanup(HsOfficePartnerEntity.builder() - .uuid(UUID.randomUUID()) .person(givenPerson) .contact(givenContact) .details(HsOfficePartnerDetailsEntity.builder() - .uuid(UUID.randomUUID()) .build()) .build()); return partnerRepo.save(newPartner); @@ -106,10 +104,9 @@ class HsOfficePartnerRepositoryIntegrationTest extends ContextBasedTest { final var givenPerson = personRepo.findPersonByOptionalNameLike("Erben Bessler").get(0); final var givenContact = contactRepo.findContactByOptionalLabelLike("forth contact").get(0); final var newPartner = toCleanup(HsOfficePartnerEntity.builder() - .uuid(UUID.randomUUID()) .person(givenPerson) .contact(givenContact) - .details(HsOfficePartnerDetailsEntity.builder().uuid(UUID.randomUUID()).build()) + .details(HsOfficePartnerDetailsEntity.builder().build()) .build()); return partnerRepo.save(newPartner); }); @@ -406,12 +403,9 @@ class HsOfficePartnerRepositoryIntegrationTest extends ContextBasedTest { final var givenPerson = personRepo.findPersonByOptionalNameLike("Erben Bessler").get(0); final var givenContact = contactRepo.findContactByOptionalLabelLike(contact).get(0); final var newPartner = HsOfficePartnerEntity.builder() - .uuid(UUID.randomUUID()) .person(givenPerson) .contact(givenContact) - .details(HsOfficePartnerDetailsEntity.builder() - .uuid(UUID.randomUUID()) - .build()) + .details(HsOfficePartnerDetailsEntity.builder().build()) .build(); toCleanup(newPartner); diff --git a/src/test/java/net/hostsharing/hsadminng/hs/office/partner/TestHsOfficePartner.java b/src/test/java/net/hostsharing/hsadminng/hs/office/partner/TestHsOfficePartner.java index 5f447665..21756b6d 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/office/partner/TestHsOfficePartner.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/office/partner/TestHsOfficePartner.java @@ -13,7 +13,6 @@ public class TestHsOfficePartner { static public HsOfficePartnerEntity HsOfficePartnerWithLegalPerson(final String tradeName) { return HsOfficePartnerEntity.builder() - .uuid(UUID.randomUUID()) .person(HsOfficePersonEntity.builder() .personType(LEGAL) .tradeName(tradeName) diff --git a/src/test/java/net/hostsharing/hsadminng/hs/office/person/HsOfficePersonControllerAcceptanceTest.java b/src/test/java/net/hostsharing/hsadminng/hs/office/person/HsOfficePersonControllerAcceptanceTest.java index 04853b9e..f92c18ff 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/office/person/HsOfficePersonControllerAcceptanceTest.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/office/person/HsOfficePersonControllerAcceptanceTest.java @@ -2,14 +2,13 @@ package net.hostsharing.hsadminng.hs.office.person; import io.restassured.RestAssured; import io.restassured.http.ContentType; -import net.hostsharing.test.Accepts; import net.hostsharing.hsadminng.HsadminNgApplication; import net.hostsharing.hsadminng.context.Context; +import net.hostsharing.test.Accepts; import net.hostsharing.test.JpaAttempt; import org.apache.commons.lang3.RandomStringUtils; import org.json.JSONException; import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; @@ -17,8 +16,7 @@ import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.transaction.annotation.Transactional; -import java.util.HashSet; -import java.util.Set; +import javax.persistence.EntityManager; import java.util.UUID; import static net.hostsharing.test.IsValidUuidMatcher.isUuidValid; @@ -31,7 +29,6 @@ import static org.hamcrest.Matchers.startsWith; webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = { HsadminNgApplication.class, JpaAttempt.class } ) -@Transactional class HsOfficePersonControllerAcceptanceTest { @LocalServerPort @@ -49,7 +46,8 @@ class HsOfficePersonControllerAcceptanceTest { @Autowired JpaAttempt jpaAttempt; - Set tempPersonUuids = new HashSet<>(); + @Autowired + EntityManager em; @Nested @Accepts({ "Person:F(Find)" }) @@ -129,9 +127,7 @@ class HsOfficePersonControllerAcceptanceTest { class AddPerson { @Test - void globalAdmin_withoutAssumedRole_canAddPerson() { - - context.define("superuser-alex@hostsharing.net"); + void globalAdmin_canAddPerson() { final var location = RestAssured // @formatter:off .given() @@ -141,7 +137,7 @@ class HsOfficePersonControllerAcceptanceTest { { "personType": "NATURAL", "familyName": "Tester", - "givenName": "Testi" + "givenName": "Temp Testi" } """) .port(port) @@ -153,23 +149,24 @@ class HsOfficePersonControllerAcceptanceTest { .body("uuid", isUuidValid()) .body("personType", is("NATURAL")) .body("familyName", is("Tester")) - .body("givenName", is("Testi")) + .body("givenName", is("Temp Testi")) .header("Location", startsWith("http://localhost")) .extract().header("Location"); // @formatter:on // finally, the new person can be accessed under the generated UUID - final var newUserUuid = toCleanup(UUID.fromString( - location.substring(location.lastIndexOf('/') + 1))); + final var newUserUuid = UUID.fromString( + location.substring(location.lastIndexOf('/') + 1)); assertThat(newUserUuid).isNotNull(); } } @Nested @Accepts({ "Person:R(Read)" }) + @Transactional class GetPerson { @Test - void globalAdmin_withoutAssumedRole_canGetArbitraryPerson() { + void globalAdmin_canGetArbitraryPerson() { context.define("superuser-alex@hostsharing.net"); final var givenPersonUuid = personRepo.findPersonByOptionalNameLike("Erben").get(0).getUuid(); @@ -192,8 +189,10 @@ class HsOfficePersonControllerAcceptanceTest { @Test @Accepts({ "Person:X(Access Control)" }) void normalUser_canNotGetUnrelatedPerson() { - context.define("superuser-alex@hostsharing.net"); - final var givenPersonUuid = personRepo.findPersonByOptionalNameLike("Erben").get(0).getUuid(); + final var givenPersonUuid = jpaAttempt.transacted(() -> { + context.define("superuser-alex@hostsharing.net"); + return personRepo.findPersonByOptionalNameLike("Erben").get(0).getUuid(); + }).returnedValue(); RestAssured // @formatter:off .given() @@ -208,8 +207,10 @@ class HsOfficePersonControllerAcceptanceTest { @Test @Accepts({ "Person:X(Access Control)" }) void personOwnerUser_canGetRelatedPerson() { - context.define("superuser-alex@hostsharing.net"); - final var givenPersonUuid = personRepo.findPersonByOptionalNameLike("Erben").get(0).getUuid(); + final var givenPersonUuid = jpaAttempt.transacted(() -> { + context.define("superuser-alex@hostsharing.net"); + return personRepo.findPersonByOptionalNameLike("Erben").get(0).getUuid(); + }).returnedValue(); RestAssured // @formatter:off .given() @@ -233,12 +234,12 @@ class HsOfficePersonControllerAcceptanceTest { @Nested @Accepts({ "Person:U(Update)" }) + @Transactional class PatchPerson { @Test - void globalAdmin_withoutAssumedRole_canPatchAllPropertiesOfArbitraryPerson() { + void globalAdmin_canPatchAllPropertiesOfArbitraryPerson() { - context.define("superuser-alex@hostsharing.net"); final var givenPerson = givenSomeTemporaryPersonCreatedBy("selfregistered-test-user@hostsharing.org"); final var location = RestAssured // @formatter:off @@ -248,9 +249,9 @@ class HsOfficePersonControllerAcceptanceTest { .body(""" { "personType": "JOINT_REPRESENTATION", - "tradeName": "Patched Trade Name", - "familyName": "Patched Family Name", - "givenName": "Patched Given Name" + "tradeName": "Temp Trade Name - patched", + "familyName": "Temp Family Name - patched", + "givenName": "Temp Given Name - patched" } """) .port(port) @@ -261,9 +262,9 @@ class HsOfficePersonControllerAcceptanceTest { .contentType(ContentType.JSON) .body("uuid", isUuidValid()) .body("personType", is("JOINT_REPRESENTATION")) - .body("tradeName", is("Patched Trade Name")) - .body("familyName", is("Patched Family Name")) - .body("givenName", is("Patched Given Name")); + .body("tradeName", is("Temp Trade Name - patched")) + .body("familyName", is("Temp Family Name - patched")) + .body("givenName", is("Temp Given Name - patched")); // @formatter:on // finally, the person is actually updated @@ -271,17 +272,16 @@ class HsOfficePersonControllerAcceptanceTest { assertThat(personRepo.findByUuid(givenPerson.getUuid())).isPresent().get() .matches(person -> { assertThat(person.getPersonType()).isEqualTo(HsOfficePersonType.JOINT_REPRESENTATION); - assertThat(person.getTradeName()).isEqualTo("Patched Trade Name"); - assertThat(person.getFamilyName()).isEqualTo("Patched Family Name"); - assertThat(person.getGivenName()).isEqualTo("Patched Given Name"); + assertThat(person.getTradeName()).isEqualTo("Temp Trade Name - patched"); + assertThat(person.getFamilyName()).isEqualTo("Temp Family Name - patched"); + assertThat(person.getGivenName()).isEqualTo("Temp Given Name - patched"); return true; }); } @Test - void globalAdmin_withoutAssumedRole_canPatchPartialPropertiesOfArbitraryPerson() { + void globalAdmin_canPatchPartialPropertiesOfArbitraryPerson() { - context.define("superuser-alex@hostsharing.net"); final var givenPerson = givenSomeTemporaryPersonCreatedBy("selfregistered-test-user@hostsharing.org"); final var location = RestAssured // @formatter:off @@ -290,8 +290,8 @@ class HsOfficePersonControllerAcceptanceTest { .contentType(ContentType.JSON) .body(""" { - "familyName": "Patched Family Name", - "givenName": "Patched Given Name" + "familyName": "Temp Family Name - patched", + "givenName": "Temp Given Name - patched" } """) .port(port) @@ -303,17 +303,18 @@ class HsOfficePersonControllerAcceptanceTest { .body("uuid", isUuidValid()) .body("personType", is(givenPerson.getPersonType().toString())) .body("tradeName", is(givenPerson.getTradeName())) - .body("familyName", is("Patched Family Name")) - .body("givenName", is("Patched Given Name")); + .body("familyName", is("Temp Family Name - patched")) + .body("givenName", is("Temp Given Name - patched")); // @formatter:on // finally, the person is actually updated + context.define("superuser-alex@hostsharing.net"); assertThat(personRepo.findByUuid(givenPerson.getUuid())).isPresent().get() .matches(person -> { assertThat(person.getPersonType()).isEqualTo(givenPerson.getPersonType()); assertThat(person.getTradeName()).isEqualTo(givenPerson.getTradeName()); - assertThat(person.getFamilyName()).isEqualTo("Patched Family Name"); - assertThat(person.getGivenName()).isEqualTo("Patched Given Name"); + assertThat(person.getFamilyName()).isEqualTo("Temp Family Name - patched"); + assertThat(person.getGivenName()).isEqualTo("Temp Given Name - patched"); return true; }); } @@ -321,11 +322,11 @@ class HsOfficePersonControllerAcceptanceTest { @Nested @Accepts({ "Person:D(Delete)" }) + @Transactional class DeletePerson { @Test - void globalAdmin_withoutAssumedRole_canDeleteArbitraryPerson() { - context.define("superuser-alex@hostsharing.net"); + void globalAdmin_canDeleteArbitraryPerson() { final var givenPerson = givenSomeTemporaryPersonCreatedBy("selfregistered-test-user@hostsharing.org"); RestAssured // @formatter:off @@ -338,6 +339,8 @@ class HsOfficePersonControllerAcceptanceTest { .statusCode(204); // @formatter:on // then the given person is gone + + context.define("superuser-alex@hostsharing.net"); assertThat(personRepo.findByUuid(givenPerson.getUuid())).isEmpty(); } @@ -362,7 +365,6 @@ class HsOfficePersonControllerAcceptanceTest { @Test @Accepts({ "Person:X(Access Control)" }) void normalUser_canNotDeleteUnrelatedPerson() { - context.define("superuser-alex@hostsharing.net"); final var givenPerson = givenSomeTemporaryPersonCreatedBy("selfregistered-test-user@hostsharing.org"); RestAssured // @formatter:off @@ -376,6 +378,7 @@ class HsOfficePersonControllerAcceptanceTest { // @formatter:on // then the given person is still there + context.define("superuser-alex@hostsharing.net"); assertThat(personRepo.findByUuid(givenPerson.getUuid())).isNotEmpty(); } } @@ -388,32 +391,21 @@ class HsOfficePersonControllerAcceptanceTest { .personType(HsOfficePersonType.LEGAL) .tradeName("Temp " + Context.getCallerMethodNameFromStackFrame(2)) .familyName(RandomStringUtils.randomAlphabetic(10) + "@example.org") - .givenName("Given Name " + RandomStringUtils.randomAlphabetic(10)) + .givenName("Temp Given Name " + RandomStringUtils.randomAlphabetic(10)) .build(); - toCleanup(newPerson.getUuid()); - return personRepo.save(newPerson); }).assertSuccessful().returnedValue(); } - private UUID toCleanup(final UUID tempPersonUuid) { - tempPersonUuids.add(tempPersonUuid); - return tempPersonUuid; - } - - @BeforeEach @AfterEach void cleanup() { - tempPersonUuids.forEach(uuid -> { - jpaAttempt.transacted(() -> { - context.define("superuser-alex@hostsharing.net", null); - System.out.println("DELETING temporary person: " + uuid); - final var entity = personRepo.findByUuid(uuid); - final var count = personRepo.deleteByUuid(uuid); - System.out.println("DELETED temporary person: " + uuid + (count > 0 ? " successful" : " failed") + - (" (" + entity.map(hsOfficePersonEntity -> hsOfficePersonEntity.toShortString()).orElse("null") + ")")); - }).assertSuccessful(); - }); + jpaAttempt.transacted(() -> { + context.define("superuser-alex@hostsharing.net", null); + em.createQuery(""" + DELETE FROM HsOfficePersonEntity p + WHERE p.tradeName LIKE 'Temp %' OR p.givenName LIKE 'Temp %' + """).executeUpdate(); + }).assertSuccessful(); } } diff --git a/src/test/java/net/hostsharing/hsadminng/hs/office/person/TestHsOfficePerson.java b/src/test/java/net/hostsharing/hsadminng/hs/office/person/TestHsOfficePerson.java index 8472f532..f4d10fda 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/office/person/TestHsOfficePerson.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/office/person/TestHsOfficePerson.java @@ -8,7 +8,6 @@ public class TestHsOfficePerson { static public HsOfficePersonEntity hsOfficePerson(final String tradeName) { return HsOfficePersonEntity.builder() - .uuid(UUID.randomUUID()) .personType(HsOfficePersonType.NATURAL) .tradeName(tradeName) .build(); diff --git a/src/test/java/net/hostsharing/hsadminng/hs/office/relationship/HsOfficeRelationshipRepositoryIntegrationTest.java b/src/test/java/net/hostsharing/hsadminng/hs/office/relationship/HsOfficeRelationshipRepositoryIntegrationTest.java index c3e76e7b..e227ebc0 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/office/relationship/HsOfficeRelationshipRepositoryIntegrationTest.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/office/relationship/HsOfficeRelationshipRepositoryIntegrationTest.java @@ -1,6 +1,5 @@ package net.hostsharing.hsadminng.hs.office.relationship; -import net.hostsharing.hsadminng.HsadminNgApplication; import net.hostsharing.hsadminng.context.Context; import net.hostsharing.hsadminng.context.ContextBasedTest; import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactRepository; @@ -15,10 +14,8 @@ import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; import org.springframework.boot.test.mock.mockito.MockBean; -import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Import; import org.springframework.orm.jpa.JpaSystemException; -import org.springframework.test.annotation.DirtiesContext; import javax.persistence.EntityManager; import javax.servlet.http.HttpServletRequest; @@ -74,7 +71,6 @@ class HsOfficeRelationshipRepositoryIntegrationTest extends ContextBasedTest { // when final var result = attempt(em, () -> { final var newRelationship = toCleanup(HsOfficeRelationshipEntity.builder() - .uuid(UUID.randomUUID()) .relAnchor(givenAnchorPerson) .relHolder(givenHolderPerson) .relType(HsOfficeRelationshipType.JOINT_AGENT) @@ -103,7 +99,6 @@ class HsOfficeRelationshipRepositoryIntegrationTest extends ContextBasedTest { final var givenHolderPerson = personRepo.findPersonByOptionalNameLike("Anita").get(0); final var givenContact = contactRepo.findContactByOptionalLabelLike("forth contact").get(0); final var newRelationship = toCleanup(HsOfficeRelationshipEntity.builder() - .uuid(UUID.randomUUID()) .relAnchor(givenAnchorPerson) .relHolder(givenHolderPerson) .relType(HsOfficeRelationshipType.JOINT_AGENT) @@ -393,7 +388,6 @@ class HsOfficeRelationshipRepositoryIntegrationTest extends ContextBasedTest { final var givenHolderPerson = personRepo.findPersonByOptionalNameLike(holderPerson).get(0); final var givenContact = contactRepo.findContactByOptionalLabelLike(contact).get(0); final var newRelationship = HsOfficeRelationshipEntity.builder() - .uuid(UUID.randomUUID()) .relType(HsOfficeRelationshipType.JOINT_AGENT) .relAnchor(givenAnchorPerson) .relHolder(givenHolderPerson) diff --git a/src/test/java/net/hostsharing/hsadminng/hs/office/sepamandate/HsOfficeSepaMandateControllerAcceptanceTest.java b/src/test/java/net/hostsharing/hsadminng/hs/office/sepamandate/HsOfficeSepaMandateControllerAcceptanceTest.java index 3f7813a9..2f0c2754 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/office/sepamandate/HsOfficeSepaMandateControllerAcceptanceTest.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/office/sepamandate/HsOfficeSepaMandateControllerAcceptanceTest.java @@ -3,14 +3,15 @@ package net.hostsharing.hsadminng.hs.office.sepamandate; import com.vladmihalcea.hibernate.type.range.Range; import io.restassured.RestAssured; import io.restassured.http.ContentType; -import net.hostsharing.test.Accepts; import net.hostsharing.hsadminng.HsadminNgApplication; import net.hostsharing.hsadminng.context.Context; import net.hostsharing.hsadminng.hs.office.bankaccount.HsOfficeBankAccountRepository; import net.hostsharing.hsadminng.hs.office.debitor.HsOfficeDebitorRepository; +import net.hostsharing.test.Accepts; import net.hostsharing.test.JpaAttempt; import org.json.JSONException; import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; @@ -18,9 +19,8 @@ import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.transaction.annotation.Transactional; +import javax.persistence.EntityManager; import java.time.LocalDate; -import java.util.HashSet; -import java.util.Set; import java.util.UUID; import static net.hostsharing.test.IsValidUuidMatcher.isUuidValid; @@ -56,7 +56,8 @@ class HsOfficeSepaMandateControllerAcceptanceTest { @Autowired JpaAttempt jpaAttempt; - Set tempSepaMandateUuids = new HashSet<>(); + @Autowired + EntityManager em; @Nested @Accepts({ "SepaMandate:F(Find)" }) @@ -131,7 +132,7 @@ class HsOfficeSepaMandateControllerAcceptanceTest { { "debitorUuid": "%s", "bankAccountUuid": "%s", - "reference": "temp ref A", + "reference": "temp ref CAT A", "validFrom": "2022-10-13" } """.formatted(givenDebitor.getUuid(), givenBankAccount.getUuid())) @@ -144,15 +145,15 @@ class HsOfficeSepaMandateControllerAcceptanceTest { .body("uuid", isUuidValid()) .body("debitor.partner.person.tradeName", is("Third OHG")) .body("bankAccount.iban", is("DE02200505501015871393")) - .body("reference", is("temp ref A")) + .body("reference", is("temp ref CAT A")) .body("validFrom", is("2022-10-13")) .body("validTo", equalTo(null)) .header("Location", startsWith("http://localhost")) .extract().header("Location"); // @formatter:on // finally, the new sepaMandate can be accessed under the generated UUID - final var newUserUuid = toCleanup(UUID.fromString( - location.substring(location.lastIndexOf('/') + 1))); + final var newUserUuid = UUID.fromString( + location.substring(location.lastIndexOf('/') + 1)); assertThat(newUserUuid).isNotNull(); } @@ -171,7 +172,7 @@ class HsOfficeSepaMandateControllerAcceptanceTest { .body(""" { "bankAccountUuid": "%s", - "reference": "temp ref A", + "reference": "temp ref CAT B", "validFrom": "2022-10-13" } """.formatted(givenBankAccount.getUuid())) @@ -197,7 +198,7 @@ class HsOfficeSepaMandateControllerAcceptanceTest { { "debitorUuid": "%s", "bankAccountUuid": "%s", - "reference": "temp ref A", + "reference": "temp ref CAT C", "validFrom": "2022-10-13", "validTo": "2024-12-31" } @@ -226,7 +227,7 @@ class HsOfficeSepaMandateControllerAcceptanceTest { { "debitorUuid": "%s", "bankAccountUuid": "%s", - "reference": "temp ref A", + "reference": "temp refCAT D", "validFrom": "2022-10-13", "validTo": "2024-12-31" } @@ -267,7 +268,7 @@ class HsOfficeSepaMandateControllerAcceptanceTest { "debitorNumber": 10001, "billingContact": { "label": "first contact" } }, - "bankAccount": { + "bankAccount": { "holder": "First GmbH", "iban": "DE02120300000000202051" }, @@ -319,7 +320,7 @@ class HsOfficeSepaMandateControllerAcceptanceTest { "debitorNumber": 10001, "billingContact": { "label": "first contact" } }, - "bankAccount": { + "bankAccount": { "holder": "First GmbH", "iban": "DE02120300000000202051" }, @@ -359,7 +360,7 @@ class HsOfficeSepaMandateControllerAcceptanceTest { .body("uuid", isUuidValid()) .body("debitor.partner.person.tradeName", is("First GmbH")) .body("bankAccount.iban", is("DE02120300000000202051")) - .body("reference", is("temp ref X")) + .body("reference", is("temp ref CAT Z")) .body("validFrom", is("2022-11-01")) .body("validTo", is("2022-12-31")); // @formatter:on @@ -369,7 +370,7 @@ class HsOfficeSepaMandateControllerAcceptanceTest { .matches(mandate -> { assertThat(mandate.getDebitor().toString()).isEqualTo("debitor(10001: First GmbH)"); assertThat(mandate.getBankAccount().toShortString()).isEqualTo("First GmbH"); - assertThat(mandate.getReference()).isEqualTo("temp ref X"); + assertThat(mandate.getReference()).isEqualTo("temp ref CAT Z"); assertThat(mandate.getValidity().asString()).isEqualTo("[2022-11-01,2023-01-01)"); return true; }); @@ -387,7 +388,7 @@ class HsOfficeSepaMandateControllerAcceptanceTest { .contentType(ContentType.JSON) .body(""" { - "reference": "new ref" + "reference": "temp ref CAT new" } """) .port(port) @@ -405,7 +406,6 @@ class HsOfficeSepaMandateControllerAcceptanceTest { return true; }); } - } @Nested @@ -435,7 +435,6 @@ class HsOfficeSepaMandateControllerAcceptanceTest { void bankAccountAdminUser_canNotDeleteRelatedSepaMandate() { context.define("superuser-alex@hostsharing.net"); final var givenSepaMandate = givenSomeTemporarySepaMandate(); - assertThat(givenSepaMandate.getReference()).isEqualTo("temp ref X"); RestAssured // @formatter:off .given() @@ -455,7 +454,6 @@ class HsOfficeSepaMandateControllerAcceptanceTest { void normalUser_canNotDeleteUnrelatedSepaMandate() { context.define("superuser-alex@hostsharing.net"); final var givenSepaMandate = givenSomeTemporarySepaMandate(); - assertThat(givenSepaMandate.getReference()).isEqualTo("temp ref X"); RestAssured // @formatter:off .given() @@ -480,32 +478,25 @@ class HsOfficeSepaMandateControllerAcceptanceTest { .uuid(UUID.randomUUID()) .debitor(givenDebitor) .bankAccount(givenBankAccount) - .reference("temp ref X") + .reference("temp ref CAT Z") .validity(Range.closedOpen( LocalDate.parse("2022-11-01"), LocalDate.parse("2023-03-31"))) .build(); - toCleanup(newSepaMandate.getUuid()); - return sepaMandateRepo.save(newSepaMandate); }).assertSuccessful().returnedValue(); } - private UUID toCleanup(final UUID tempSepaMandateUuid) { - tempSepaMandateUuids.add(tempSepaMandateUuid); - return tempSepaMandateUuid; - } - + @BeforeEach @AfterEach void cleanup() { - tempSepaMandateUuids.forEach(uuid -> { - jpaAttempt.transacted(() -> { - context.define("superuser-alex@hostsharing.net", null); - System.out.println("DELETING temporary sepaMandate: " + uuid); - final var count = sepaMandateRepo.deleteByUuid(uuid); - System.out.println("DELETED temporary sepaMandate: " + uuid + (count > 0 ? " successful" : " failed")); - }); - }); + jpaAttempt.transacted(() -> { + context.define("superuser-alex@hostsharing.net", null); + final var count = em.createQuery("DELETE FROM HsOfficeSepaMandateEntity s WHERE s.reference like 'temp %'") + .executeUpdate(); + if (count == 0) { + System.out.println("nothing deleted"); + } + }).assertSuccessful(); } - } diff --git a/src/test/java/net/hostsharing/hsadminng/hs/office/sepamandate/HsOfficeSepaMandateRepositoryIntegrationTest.java b/src/test/java/net/hostsharing/hsadminng/hs/office/sepamandate/HsOfficeSepaMandateRepositoryIntegrationTest.java index 1b5c0264..4a6a8d0f 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/office/sepamandate/HsOfficeSepaMandateRepositoryIntegrationTest.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/office/sepamandate/HsOfficeSepaMandateRepositoryIntegrationTest.java @@ -16,15 +16,15 @@ import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; import org.springframework.boot.test.mock.mockito.MockBean; -import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Import; import org.springframework.orm.jpa.JpaSystemException; -import org.springframework.test.annotation.DirtiesContext; +import org.springframework.transaction.annotation.Transactional; import javax.persistence.EntityManager; import javax.servlet.http.HttpServletRequest; import java.time.LocalDate; -import java.util.*; +import java.util.Arrays; +import java.util.List; import static net.hostsharing.hsadminng.rbac.rbacgrant.RawRbacGrantEntity.grantDisplaysOf; import static net.hostsharing.hsadminng.rbac.rbacrole.RawRbacRoleEntity.roleNamesOf; @@ -33,7 +33,7 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assumptions.assumeThat; @DataJpaTest -@Import( { Context.class, JpaAttempt.class }) +@Import({ Context.class, JpaAttempt.class }) class HsOfficeSepaMandateRepositoryIntegrationTest extends ContextBasedTest { @Autowired @@ -52,16 +52,14 @@ class HsOfficeSepaMandateRepositoryIntegrationTest extends ContextBasedTest { RawRbacGrantRepository rawGrantRepo; @Autowired - EntityManager em; + JpaAttempt jpaAttempt; @Autowired - JpaAttempt jpaAttempt; + EntityManager em; @MockBean HttpServletRequest request; - Set tempEntities = new HashSet<>(); - @Nested class CreateSepaMandate { @@ -75,14 +73,13 @@ class HsOfficeSepaMandateRepositoryIntegrationTest extends ContextBasedTest { // when final var result = attempt(em, () -> { - final var newSepaMandate = toCleanup(HsOfficeSepaMandateEntity.builder() - .uuid(UUID.randomUUID()) + final var newSepaMandate = HsOfficeSepaMandateEntity.builder() .debitor(givenDebitor) .bankAccount(givenBankAccount) .reference("temp ref A") .validity(Range.closedOpen( LocalDate.parse("2020-01-01"), LocalDate.parse("2023-01-01"))) - .build()); + .build(); return sepaMandateRepo.save(newSepaMandate); }); @@ -108,14 +105,13 @@ class HsOfficeSepaMandateRepositoryIntegrationTest extends ContextBasedTest { attempt(em, () -> { final var givenDebitor = debitorRepo.findDebitorByOptionalNameLike("First").get(0); final var givenBankAccount = bankAccountRepo.findByOptionalHolderLike("Paul Winkler").get(0); - final var newSepaMandate = toCleanup(HsOfficeSepaMandateEntity.builder() - .uuid(UUID.randomUUID()) + final var newSepaMandate = HsOfficeSepaMandateEntity.builder() .debitor(givenDebitor) .bankAccount(givenBankAccount) .reference("temp ref B") .validity(Range.closedOpen( LocalDate.parse("2020-01-01"), LocalDate.parse("2023-01-01"))) - .build()); + .build(); return sepaMandateRepo.save(newSepaMandate); }); @@ -255,7 +251,7 @@ class HsOfficeSepaMandateRepositoryIntegrationTest extends ContextBasedTest { context("superuser-alex@hostsharing.net"); givenSepaMandate.setValidity(Range.closedOpen( givenSepaMandate.getValidity().lower(), newValidityEnd)); - return toCleanup(sepaMandateRepo.save(givenSepaMandate)); + return sepaMandateRepo.save(givenSepaMandate); }); // then @@ -408,18 +404,10 @@ class HsOfficeSepaMandateRepositoryIntegrationTest extends ContextBasedTest { @BeforeEach @AfterEach + @Transactional void cleanup() { - tempEntities.forEach(tempSepaMandate -> { - jpaAttempt.transacted(() -> { - context("superuser-alex@hostsharing.net", null); - System.out.println("DELETING temporary sepaMandate: " + tempSepaMandate.toString()); - sepaMandateRepo.deleteByUuid(tempSepaMandate.getUuid()); - }); - }); - jpaAttempt.transacted(() -> { - context("superuser-alex@hostsharing.net", null); - em.createQuery("DELETE FROM HsOfficeSepaMandateEntity WHERE reference like 'temp ref%'"); - }); + context("superuser-alex@hostsharing.net", null); + em.createQuery("DELETE FROM HsOfficeSepaMandateEntity WHERE reference like 'temp ref%'").executeUpdate(); } private HsOfficeSepaMandateEntity givenSomeTemporarySepaMandateBessler(final String bankAccountHolder) { @@ -428,7 +416,6 @@ class HsOfficeSepaMandateRepositoryIntegrationTest extends ContextBasedTest { final var givenDebitor = debitorRepo.findDebitorByOptionalNameLike("First").get(0); final var givenBankAccount = bankAccountRepo.findByOptionalHolderLike(bankAccountHolder).get(0); final var newSepaMandate = HsOfficeSepaMandateEntity.builder() - .uuid(UUID.randomUUID()) .debitor(givenDebitor) .bankAccount(givenBankAccount) .reference("temp ref X") @@ -436,17 +423,10 @@ class HsOfficeSepaMandateRepositoryIntegrationTest extends ContextBasedTest { LocalDate.parse("2020-01-01"), LocalDate.parse("2023-01-01"))) .build(); - toCleanup(newSepaMandate); - return sepaMandateRepo.save(newSepaMandate); }).assertSuccessful().returnedValue(); } - private HsOfficeSepaMandateEntity toCleanup(final HsOfficeSepaMandateEntity tempEntity) { - tempEntities.add(tempEntity); - return tempEntity; - } - void exactlyTheseSepaMandatesAreReturned( final List actualResult, final String... sepaMandateNames) { diff --git a/src/test/java/net/hostsharing/hsadminng/rbac/rbacrole/RbacRoleControllerRestTest.java b/src/test/java/net/hostsharing/hsadminng/rbac/rbacrole/RbacRoleControllerRestTest.java index 54c89998..f3ea4285 100644 --- a/src/test/java/net/hostsharing/hsadminng/rbac/rbacrole/RbacRoleControllerRestTest.java +++ b/src/test/java/net/hostsharing/hsadminng/rbac/rbacrole/RbacRoleControllerRestTest.java @@ -13,6 +13,8 @@ import org.springframework.test.context.junit4.SpringRunner; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; +import javax.persistence.EntityManager; + import static java.util.Arrays.asList; import static net.hostsharing.hsadminng.rbac.rbacrole.TestRbacRole.*; import static org.hamcrest.Matchers.hasSize; @@ -35,6 +37,9 @@ class RbacRoleControllerRestTest { @MockBean RbacRoleRepository rbacRoleRepository; + @MockBean + EntityManager em; + @Test void apiCustomersWillReturnCustomersFromRepository() throws Exception { diff --git a/src/test/java/net/hostsharing/hsadminng/rbac/rbacuser/RbacUserControllerRestTest.java b/src/test/java/net/hostsharing/hsadminng/rbac/rbacuser/RbacUserControllerRestTest.java index a74c4de7..e24e2edd 100644 --- a/src/test/java/net/hostsharing/hsadminng/rbac/rbacuser/RbacUserControllerRestTest.java +++ b/src/test/java/net/hostsharing/hsadminng/rbac/rbacuser/RbacUserControllerRestTest.java @@ -13,6 +13,7 @@ import org.springframework.test.context.junit4.SpringRunner; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; +import javax.persistence.EntityManager; import java.util.UUID; import static net.hostsharing.test.IsValidUuidMatcher.isUuidValid; @@ -36,6 +37,9 @@ class RbacUserControllerRestTest { @MockBean RbacUserRepository rbacUserRepository; + @MockBean + EntityManager em; + @Test void createUserUsesGivenUuid() throws Exception { // given diff --git a/src/test/java/net/hostsharing/hsadminng/test/cust/TestCustomer.java b/src/test/java/net/hostsharing/hsadminng/test/cust/TestCustomer.java index dcee7317..7d5b0b43 100644 --- a/src/test/java/net/hostsharing/hsadminng/test/cust/TestCustomer.java +++ b/src/test/java/net/hostsharing/hsadminng/test/cust/TestCustomer.java @@ -8,6 +8,6 @@ public class TestCustomer { static final TestCustomerEntity yyy = hsCustomer("yyy", 10002, "yyy@example.com"); static public TestCustomerEntity hsCustomer(final String prefix, final int reference, final String adminName) { - return new TestCustomerEntity(randomUUID(), prefix, reference, adminName); + return new TestCustomerEntity(null, prefix, reference, adminName); } } diff --git a/src/test/java/net/hostsharing/hsadminng/test/cust/TestCustomerControllerAcceptanceTest.java b/src/test/java/net/hostsharing/hsadminng/test/cust/TestCustomerControllerAcceptanceTest.java index a2bd0b78..296fc29b 100644 --- a/src/test/java/net/hostsharing/hsadminng/test/cust/TestCustomerControllerAcceptanceTest.java +++ b/src/test/java/net/hostsharing/hsadminng/test/cust/TestCustomerControllerAcceptanceTest.java @@ -6,6 +6,7 @@ import net.hostsharing.hsadminng.HsadminNgApplication; import net.hostsharing.hsadminng.context.Context; import net.hostsharing.test.JpaAttempt; import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; @@ -13,8 +14,7 @@ import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.transaction.annotation.Transactional; -import java.util.HashSet; -import java.util.Set; +import javax.persistence.EntityManager; import java.util.UUID; import static org.assertj.core.api.Assertions.assertThat; @@ -43,7 +43,8 @@ class TestCustomerControllerAcceptanceTest { @Autowired JpaAttempt jpaAttempt; - Set tempPartnerUuids = new HashSet<>(); + @Autowired + EntityManager em; @Nested class ListCustomers { @@ -144,51 +145,13 @@ class TestCustomerControllerAcceptanceTest { .extract().header("Location"); // @formatter:on // finally, the new customer can be viewed by its own admin - final var newUserUuid = toCleanup(UUID.fromString( - location.substring(location.lastIndexOf('/') + 1))); + final var newUserUuid = UUID.fromString( + location.substring(location.lastIndexOf('/') + 1)); context.define("customer-admin@uuu.example.com"); assertThat(testCustomerRepository.findByUuid(newUserUuid)) .hasValueSatisfying(c -> assertThat(c.getPrefix()).isEqualTo("uuu")); } - @Test - void globalAdmin_withoutAssumedRole_canAddCustomerWithGivenUuid() { - - final var givenUuid = toCleanup(UUID.randomUUID()); - - final var location = RestAssured // @formatter:off - .given() - .header("current-user", "superuser-alex@hostsharing.net") - .contentType(ContentType.JSON) - .body(""" - { - "uuid": "%s", - "reference": 90010, - "prefix": "vvv", - "adminUserName": "customer-admin@vvv.example.com" - } - """.formatted(givenUuid)) - .port(port) - .when() - .post("http://localhost/api/test/customers") - .then().assertThat() - .statusCode(201) - .contentType(ContentType.JSON) - .body("prefix", is("vvv")) - .header("Location", startsWith("http://localhost")) - .extract().header("Location"); // @formatter:on - - // finally, the new customer can be viewed by its own admin - final var newUserUuid = UUID.fromString( - location.substring(location.lastIndexOf('/') + 1)); - context.define("customer-admin@vvv.example.com"); - assertThat(testCustomerRepository.findByUuid(newUserUuid)) - .hasValueSatisfying(c -> { - assertThat(c.getPrefix()).isEqualTo("vvv"); - assertThat(c.getUuid()).isEqualTo(givenUuid); - }); - } - @Test void globalAdmin_withAssumedCustomerAdminRole_canNotAddCustomer() { @@ -266,26 +229,14 @@ class TestCustomerControllerAcceptanceTest { .body("message", containsString("line: 1, column: 1")); // @formatter:on } - - } - - private UUID toCleanup(final UUID tempPartnerUuid) { - tempPartnerUuids.add(tempPartnerUuid); - return tempPartnerUuid; } + @BeforeEach @AfterEach void cleanup() { - tempPartnerUuids.forEach(uuid -> { - jpaAttempt.transacted(() -> { - context.define("superuser-alex@hostsharing.net", null); - System.out.println("DELETING temporary partner: " + uuid); - final var entity = testCustomerRepository.findByUuid(uuid); - final var count = testCustomerRepository.deleteByUuid(uuid); - System.out.println( - "DELETED temporary partner: " + uuid + (count > 0 ? " successful" : " failed") + " (" + entity.map( - TestCustomerEntity::getPrefix).orElse("???") + ")"); - }).assertSuccessful(); - }); + jpaAttempt.transacted(() -> { + context.define("superuser-alex@hostsharing.net", null); + em.createQuery("DELETE FROM TestCustomerEntity c WHERE c.reference < 99900").executeUpdate(); + }).assertSuccessful(); } } diff --git a/src/test/java/net/hostsharing/hsadminng/test/cust/TestCustomerRepositoryIntegrationTest.java b/src/test/java/net/hostsharing/hsadminng/test/cust/TestCustomerRepositoryIntegrationTest.java index c0356e15..6d3471f1 100644 --- a/src/test/java/net/hostsharing/hsadminng/test/cust/TestCustomerRepositoryIntegrationTest.java +++ b/src/test/java/net/hostsharing/hsadminng/test/cust/TestCustomerRepositoryIntegrationTest.java @@ -8,9 +8,7 @@ import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; import org.springframework.boot.test.mock.mockito.MockBean; -import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Import; -import org.springframework.test.annotation.DirtiesContext; import javax.persistence.EntityManager; import javax.persistence.PersistenceException; diff --git a/src/test/java/net/hostsharing/test/JpaAttempt.java b/src/test/java/net/hostsharing/test/JpaAttempt.java index 6a71711c..18c257ec 100644 --- a/src/test/java/net/hostsharing/test/JpaAttempt.java +++ b/src/test/java/net/hostsharing/test/JpaAttempt.java @@ -1,5 +1,6 @@ package net.hostsharing.test; +import org.assertj.core.api.ObjectAssert; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.NestedExceptionUtils; import org.springframework.stereotype.Service; @@ -105,6 +106,11 @@ public class JpaAttempt { return result; } + public ObjectAssert assertThatResult() { + assertSuccessful(); + return assertThat(returnedValue()); + } + public RuntimeException caughtException() { return exception; } diff --git a/src/test/java/net/hostsharing/test/MapperUnitTest.java b/src/test/java/net/hostsharing/test/MapperUnitTest.java index 37e06153..2af97741 100644 --- a/src/test/java/net/hostsharing/test/MapperUnitTest.java +++ b/src/test/java/net/hostsharing/test/MapperUnitTest.java @@ -1,41 +1,35 @@ package net.hostsharing.test; -import lombok.AllArgsConstructor; -import lombok.Getter; -import lombok.NoArgsConstructor; -import lombok.Setter; +import lombok.*; +import net.hostsharing.hsadminng.errors.DisplayName; import net.hostsharing.hsadminng.mapper.Mapper; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; +import javax.persistence.EntityManager; +import javax.persistence.ManyToOne; +import javax.validation.ValidationException; import java.util.List; +import java.util.UUID; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.catchThrowable; import static org.junit.jupiter.api.Assertions.fail; +import static org.mockito.Mockito.when; +@ExtendWith(MockitoExtension.class) class MapperUnitTest { - private Mapper mapper = new Mapper(); + @Mock + EntityManager em; - @Getter - @Setter - @NoArgsConstructor - @AllArgsConstructor - public static class SourceBean { + @InjectMocks + Mapper mapper; - private String a; - private String b; - } - - @Getter - @Setter - @NoArgsConstructor - @AllArgsConstructor - public static class TargetBean { - - private String a; - private String b; - private String c; - } + final UUID GIVEN_UUID = UUID.randomUUID(); @Test void mapsNullBeanToNull() { @@ -46,48 +40,198 @@ class MapperUnitTest { @Test void mapsBean() { - final SourceBean givenSource = new SourceBean("1234", "Text"); + final SourceBean givenSource = SourceBean.builder().a("1234").b("Text").build(); final var result = mapper.map(givenSource, TargetBean.class); assertThat(result).usingRecursiveComparison().isEqualTo( - new TargetBean("1234", "Text", null) + TargetBean.builder().a("1234").b("Text").build() ); } + @Test + void mapsBeanWithExistingSubEntity() { + final SourceBean givenSource = SourceBean.builder().a("1234").b("Text").s1(new SubSourceBean1(GIVEN_UUID)).build(); + when(em.find(SubTargetBean1.class, GIVEN_UUID)).thenReturn(new SubTargetBean1(GIVEN_UUID, "xxx")); + + final var result = mapper.map(givenSource, TargetBean.class); + assertThat(result).usingRecursiveComparison().isEqualTo( + TargetBean.builder().a("1234").b("Text").s1(new SubTargetBean1(GIVEN_UUID, "xxx")).build() + ); + } + + @Test + void mapsBeanWithSubEntityWithNullUuid() { + final SourceBean givenSource = SourceBean.builder().a("1234").b("Text").s1(new SubSourceBean1(null)).build(); + + final var result = mapper.map(givenSource, TargetBean.class); + assertThat(result).usingRecursiveComparison().isEqualTo( + TargetBean.builder().a("1234").b("Text").s1(new SubTargetBean1(null, null)).build() + ); + } + + @Test + void mapsBeanWithSubEntityWithoutUuidField() { + final SourceBean givenSource = SourceBean.builder().a("1234").b("Text").s3(new SubSourceBean3("xxx")).build(); + + final var result = mapper.map(givenSource, TargetBean.class); + assertThat(result).usingRecursiveComparison().isEqualTo( + TargetBean.builder().a("1234").b("Text").s3(new SubTargetBean3("xxx")).build() + ); + } + + @Test + void mapsBeanWithSubEntityNotFound() { + final SourceBean givenSource = SourceBean.builder().a("1234").b("Text").s1(new SubSourceBean1(GIVEN_UUID)).build(); + when(em.find(SubTargetBean1.class, GIVEN_UUID)).thenReturn(null); + + final var exception = catchThrowable(() -> + mapper.map(givenSource, TargetBean.class) + ); + + assertThat(exception).isInstanceOf(ValidationException.class) + .hasMessage("Unable to find SubTargetBean1 with uuid " + GIVEN_UUID); + } + + @Test + void mapsBeanWithSubEntityNotFoundAndDisplayName() { + final SourceBean givenSource = SourceBean.builder().a("1234").b("Text").s2(new SubSourceBean2(GIVEN_UUID)).build(); + when(em.find(SubTargetBean2.class, GIVEN_UUID)).thenReturn(null); + + final var exception = catchThrowable(() -> + mapper.map(givenSource, TargetBean.class) + ); + + assertThat(exception).isInstanceOf(ValidationException.class) + .hasMessage("Unable to find SomeDisplayName with uuid " + GIVEN_UUID); + } + @Test void mapsBeanWithPostmapper() { - final SourceBean givenSource = new SourceBean("1234", "Text"); + final SourceBean givenSource = SourceBean.builder().a("1234").b("Text").build(); final var result = mapper.map(givenSource, TargetBean.class, (s, t) -> {t.setC("Extra");}); assertThat(result).usingRecursiveComparison().isEqualTo( - new TargetBean("1234", "Text", "Extra") + TargetBean.builder().a("1234").b("Text").c("Extra").build() ); } @Test void mapsList() { final var givenSource = List.of( - new SourceBean("111", "Text A"), - new SourceBean("222", "Text B"), - new SourceBean("333", "Text C")); + SourceBean.builder().a("111").b("Text A").build(), + SourceBean.builder().a("222").b("Text B").build(), + SourceBean.builder().a("333").b("Text C").build()); final var result = mapper.mapList(givenSource, TargetBean.class); assertThat(result).usingRecursiveComparison().isEqualTo( List.of( - new TargetBean("111", "Text A", null), - new TargetBean("222", "Text B", null), - new TargetBean("333", "Text C", null))); + TargetBean.builder().a("111").b("Text A").build(), + TargetBean.builder().a("222").b("Text B").build(), + TargetBean.builder().a("333").b("Text C").build())); } @Test void mapsListWithPostMapper() { final var givenSource = List.of( - new SourceBean("111", "Text A"), - new SourceBean("222", "Text B"), - new SourceBean("333", "Text C")); + SourceBean.builder().a("111").b("Text A").build(), + SourceBean.builder().a("222").b("Text B").build(), + SourceBean.builder().a("333").b("Text C").build()); final var result = mapper.mapList(givenSource, TargetBean.class, (s, t) -> {t.setC("Extra");}); assertThat(result).usingRecursiveComparison().isEqualTo( List.of( - new TargetBean("111", "Text A", "Extra"), - new TargetBean("222", "Text B", "Extra"), - new TargetBean("333", "Text C", "Extra"))); + TargetBean.builder().a("111").b("Text A").c("Extra").build(), + TargetBean.builder().a("222").b("Text B").c("Extra").build(), + TargetBean.builder().a("333").b("Text C").c("Extra").build())); + } + + @Getter + @Setter + @Builder + @NoArgsConstructor + @AllArgsConstructor + public static class SourceBean { + + private String a; + private String b; + private SubSourceBean1 s1; + private SubSourceBean2 s2; + private SubSourceBean3 s3; + } + + @Getter + @Setter + @NoArgsConstructor + @AllArgsConstructor + public static class SubSourceBean1 { + + private UUID uuid; + } + + @Getter + @Setter + @NoArgsConstructor + @AllArgsConstructor + public static class SubSourceBean2 { + + private UUID uuid; + } + + @Getter + @Setter + @NoArgsConstructor + @AllArgsConstructor + public static class SubSourceBean3 { + + private String x; + } + + @Getter + @Setter + @Builder + @NoArgsConstructor + @AllArgsConstructor + public static class TargetBean { + + private String a; + private String b; + private String c; + + @ManyToOne + private SubTargetBean1 s1; + + @ManyToOne + private SubTargetBean2 s2; + + @ManyToOne + private SubTargetBean3 s3; + } + + @Getter + @Setter + @NoArgsConstructor + @AllArgsConstructor + public static class SubTargetBean1 { + + private UUID uuid; + private String x; + } + + @Getter + @Setter + @NoArgsConstructor + @AllArgsConstructor + @DisplayName("SomeDisplayName") + public static class SubTargetBean2 { + + private UUID uuid; + private String x; + } + + + @Getter + @Setter + @NoArgsConstructor + @AllArgsConstructor + public static class SubTargetBean3 { + + private String x; } }