From eba39ff27ad25636a2bcd193fd312904c052410d Mon Sep 17 00:00:00 2001 From: Michael Hoennig Date: Sun, 12 Jan 2025 13:40:32 +0100 Subject: [PATCH 01/35] upgrade to Spring Boot 3.4.1 and fixed most issues, except one particular strange RBAC problem --- .tc-environment | 2 +- .unset-environment | 2 +- build.gradle | 10 +- etc/allowed-licenses.json | 22 ++-- .../RestResponseEntityExceptionHandler.java | 3 +- .../HsUnixUserHostingAssetValidator.java | 2 + ...OfficeCoopSharesTransactionController.java | 5 +- .../debitor/HsOfficeDebitorController.java | 30 +++-- .../HsOfficeMembershipController.java | 18 ++- .../HsOfficeMembershipEntityPatcher.java | 6 +- .../partner/HsOfficePartnerRepository.java | 39 ++++-- .../person/HsOfficePersonRealEntity.java | 2 - .../HsOfficeSepaMandateController.java | 26 +++- .../hs-office/hs-office-debitor-schemas.yaml | 1 + ...OfficeContactControllerAcceptanceTest.java | 1 - ...esTransactionControllerAcceptanceTest.java | 118 ++++++++++-------- ...opSharesTransactionControllerRestTest.java | 4 +- ...iceMembershipControllerAcceptanceTest.java | 1 - ...OfficeMembershipEntityPatcherUnitTest.java | 4 +- ...fficePartnerRepositoryIntegrationTest.java | 60 ++++----- ...sOfficePersonControllerAcceptanceTest.java | 1 - ...ceSepaMandateControllerAcceptanceTest.java | 10 +- src/test/resources/application.yml | 2 +- 23 files changed, 221 insertions(+), 148 deletions(-) diff --git a/.tc-environment b/.tc-environment index ecc6dc9a..595d0096 100644 --- a/.tc-environment +++ b/.tc-environment @@ -4,5 +4,5 @@ export HSADMINNG_POSTGRES_ADMIN_PASSWORD= export HSADMINNG_POSTGRES_RESTRICTED_USERNAME=restricted export HSADMINNG_SUPERUSER=superuser-alex@hostsharing.net export HSADMINNG_MIGRATION_DATA_PATH=migration -export LIQUIBASE_CONTEXT= +export LIQUIBASE_COMMAND_CONTEXT_FILTER= export LANG=en_US.UTF-8 diff --git a/.unset-environment b/.unset-environment index a9e4ee81..fbc180cc 100644 --- a/.unset-environment +++ b/.unset-environment @@ -4,5 +4,5 @@ unset HSADMINNG_POSTGRES_ADMIN_PASSWORD unset HSADMINNG_POSTGRES_RESTRICTED_USERNAME unset HSADMINNG_SUPERUSER unset HSADMINNG_MIGRATION_DATA_PATH -unset LIQUIBASE_CONTEXT +unset LIQUIBASE_COMMAND_CONTEXT_FILTER diff --git a/build.gradle b/build.gradle index 7646a33b..2ef4a819 100644 --- a/build.gradle +++ b/build.gradle @@ -1,11 +1,11 @@ plugins { id 'java' - id 'org.springframework.boot' version '3.3.7' + id 'org.springframework.boot' version '3.4.1' id 'io.spring.dependency-management' version '1.1.7' id 'io.openapiprocessor.openapi-processor' version '2023.2' id 'com.github.jk1.dependency-license-report' version '2.9' id "org.owasp.dependencycheck" version "11.1.1" - id "com.diffplug.spotless" version "7.0.0" + id "com.diffplug.spotless" version "7.0.1" id 'jacoco' id 'info.solidsoft.pitest' version '1.15.0' id 'se.patrikerdes.use-latest-versions' version '0.2.18' @@ -20,6 +20,8 @@ wrapper { gradleVersion = '8.5' } +// FIXME: Mockito is currently self-attaching to enable the inline-mock-maker. This will no longer work in future releases of the JDK. Please add Mockito as an agent to your build what is described in Mockito's documentation: https://javadoc.io/doc/org.mockito/mockito-core/latest/org/mockito/Mockito.html#0.3 + configurations { compileOnly { extendsFrom annotationProcessor @@ -61,7 +63,7 @@ dependencies { implementation 'org.springframework.boot:spring-boot-starter-actuator' implementation 'org.springframework.boot:spring-boot-starter-security' implementation 'com.github.gavlyukovskiy:datasource-proxy-spring-boot-starter:1.10.0' - implementation 'org.springdoc:springdoc-openapi:2.6.0' + implementation 'org.springdoc:springdoc-openapi:2.8.1' implementation 'org.postgresql:postgresql:42.7.4' implementation 'org.liquibase:liquibase-core:4.30.0' implementation 'io.hypersistence:hypersistence-utils-hibernate-63:3.9.0' @@ -71,7 +73,7 @@ dependencies { implementation 'net.java.dev.jna:jna:5.16.0' implementation 'org.modelmapper:modelmapper:3.2.2' implementation 'org.iban4j:iban4j:3.2.10-RELEASE' - implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.6.0' + implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.8.1' implementation 'org.reflections:reflections:0.10.2' compileOnly 'org.projectlombok:lombok' diff --git a/etc/allowed-licenses.json b/etc/allowed-licenses.json index ff50a78f..447f5c62 100644 --- a/etc/allowed-licenses.json +++ b/etc/allowed-licenses.json @@ -5,9 +5,23 @@ { "moduleLicense": "Apache-2.0" }, { "moduleLicense": "Apache License 2.0" }, { "moduleLicense": "Apache License v2.0" }, + { "moduleLicense": "Apache License Version 2.0" }, { "moduleLicense": "Apache License, Version 2.0" }, + { "moduleLicense": "The Apache License, Version 2.0" }, { "moduleLicense": "The Apache Software License, Version 2.0" }, + { + "moduleLicense": null, + "#moduleLicense": "Apache License 2.0, see https://github.com/springdoc/springdoc-openapi/blob/main/LICENSE", + "moduleVersion": "2.4.0", + "moduleName": "org.springdoc:springdoc-openapi" + }, + { + "moduleLicense": null, + "moduleVersion": "1.0.0", + "moduleName": "org.jspecify:jspecify" + }, + { "moduleLicense": "BSD License" }, { "moduleLicense": "BSD-2-Clause" }, { "moduleLicense": "BSD-3-Clause" }, @@ -46,14 +60,8 @@ { "moduleLicense": "Public Domain, per Creative Commons CC0", "moduleVersion": "2.0.3" - }, - - { - "moduleLicense": null, - "#moduleLicense": "Apache License 2.0, see https://github.com/springdoc/springdoc-openapi/blob/main/LICENSE", - "moduleVersion": "2.4.0", - "moduleName": "org.springdoc:springdoc-openapi" } + ] } diff --git a/src/main/java/net/hostsharing/hsadminng/errors/RestResponseEntityExceptionHandler.java b/src/main/java/net/hostsharing/hsadminng/errors/RestResponseEntityExceptionHandler.java index c366d7bc..64b72ef8 100644 --- a/src/main/java/net/hostsharing/hsadminng/errors/RestResponseEntityExceptionHandler.java +++ b/src/main/java/net/hostsharing/hsadminng/errors/RestResponseEntityExceptionHandler.java @@ -97,6 +97,7 @@ public class RestResponseEntityExceptionHandler return errorResponse(request, HttpStatus.valueOf(statusCode.value()), Optional.ofNullable(response.getBody()).map(Object::toString).orElse(firstMessageLine(exc))); } + @Override @SuppressWarnings("unchecked,rawtypes") protected ResponseEntity handleHttpMessageNotReadable( @@ -131,7 +132,7 @@ public class RestResponseEntityExceptionHandler final HttpStatusCode status, final WebRequest request) { final var errorList = exc - .getAllValidationResults() + .getAllValidationResults() // FIXME: deprecated .stream() .map(ParameterValidationResult::getResolvableErrors) .flatMap(Collection::stream) diff --git a/src/main/java/net/hostsharing/hsadminng/hs/hosting/asset/validators/HsUnixUserHostingAssetValidator.java b/src/main/java/net/hostsharing/hsadminng/hs/hosting/asset/validators/HsUnixUserHostingAssetValidator.java index 024866c2..9f2ac336 100644 --- a/src/main/java/net/hostsharing/hsadminng/hs/hosting/asset/validators/HsUnixUserHostingAssetValidator.java +++ b/src/main/java/net/hostsharing/hsadminng/hs/hosting/asset/validators/HsUnixUserHostingAssetValidator.java @@ -6,6 +6,7 @@ import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType; import net.hostsharing.hsadminng.hs.validation.PropertiesProvider; import jakarta.persistence.EntityManager; +import jakarta.persistence.FlushModeType; import java.util.regex.Pattern; import static net.hostsharing.hsadminng.hs.validation.BooleanProperty.booleanProperty; @@ -53,6 +54,7 @@ class HsUnixUserHostingAssetValidator extends HostingAssetEntityValidator { } private static Integer computeUserId(final EntityManager em, final PropertiesProvider propertiesProvider) { + em.setFlushMode(FlushModeType.COMMIT); // FIXME: check and remove or reset final Object result = em.createNativeQuery("SELECT nextval('hs_hosting.asset_unixuser_system_id_seq')", Integer.class) .getSingleResult(); return (Integer) result; 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 b903dd85..9afef7da 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 @@ -8,7 +8,7 @@ import net.hostsharing.hsadminng.hs.office.generated.api.v1.api.HsOfficeCoopShar import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeCoopSharesTransactionInsertResource; import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeCoopSharesTransactionResource; import net.hostsharing.hsadminng.errors.MultiValidationException; -import net.hostsharing.hsadminng.mapper.StandardMapper; +import net.hostsharing.hsadminng.mapper.StrictMapper; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.format.annotation.DateTimeFormat; import org.springframework.format.annotation.DateTimeFormat.ISO; @@ -33,14 +33,13 @@ public class HsOfficeCoopSharesTransactionController implements HsOfficeCoopShar private Context context; @Autowired - private StandardMapper mapper; + private StrictMapper mapper; @Autowired private HsOfficeCoopSharesTransactionRepository coopSharesTransactionRepo; @Override @Transactional(readOnly = true) - @Timed("app.office.coopShares.api.getListOfCoopShares") public ResponseEntity> getListOfCoopShares( final String currentSubject, 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 1e82b848..089d85b2 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 @@ -2,13 +2,14 @@ package net.hostsharing.hsadminng.hs.office.debitor; import io.micrometer.core.annotation.Timed; import net.hostsharing.hsadminng.context.Context; +import net.hostsharing.hsadminng.hs.office.bankaccount.HsOfficeBankAccountRepository; import net.hostsharing.hsadminng.hs.office.generated.api.v1.api.HsOfficeDebitorsApi; import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeDebitorInsertResource; import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeDebitorPatchResource; import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeDebitorResource; import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationRealEntity; import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationRealRepository; -import net.hostsharing.hsadminng.mapper.StandardMapper; +import net.hostsharing.hsadminng.mapper.StrictMapper; import net.hostsharing.hsadminng.persistence.EntityExistsValidator; import org.apache.commons.lang3.Validate; import org.hibernate.Hibernate; @@ -36,13 +37,16 @@ public class HsOfficeDebitorController implements HsOfficeDebitorsApi { private Context context; @Autowired - private StandardMapper mapper; + private StrictMapper mapper; @Autowired private HsOfficeDebitorRepository debitorRepo; @Autowired - private HsOfficeRelationRealRepository relrealRepo; + private HsOfficeRelationRealRepository realRelRepo; + + @Autowired + private HsOfficeBankAccountRepository bankAccountRepo; @Autowired private EntityExistsValidator entityValidator; @@ -88,18 +92,18 @@ public class HsOfficeDebitorController implements HsOfficeDebitorsApi { Validate.isTrue(body.getDebitorRel() == null || body.getDebitorRel().getMark() == null, "ERROR: [400] debitorRel.mark must be null"); - final var entityToSave = mapper.map(body, HsOfficeDebitorEntity.class); - if (body.getDebitorRel() != null) { + final var entityToSave = mapper.map(body, HsOfficeDebitorEntity.class, RESOURCE_TO_ENTITY_POSTMAPPER); + if (body.getDebitorRel() != null) { // FIXME: move this into RESOURCE_TO_ENTITY_POSTMAPPER final var debitorRel = mapper.map("debitorRel.", body.getDebitorRel(), HsOfficeRelationRealEntity.class); debitorRel.setType(DEBITOR); entityValidator.validateEntityExists("debitorRel.anchorUuid", debitorRel.getAnchor()); entityValidator.validateEntityExists("debitorRel.holderUuid", debitorRel.getHolder()); entityValidator.validateEntityExists("debitorRel.contactUuid", debitorRel.getContact()); - entityToSave.setDebitorRel(relrealRepo.save(debitorRel)); + entityToSave.setDebitorRel(realRelRepo.save(debitorRel)); } else { - final var debitorRelOptional = relrealRepo.findByUuid(body.getDebitorRelUuid()); + final var debitorRelOptional = realRelRepo.findByUuid(body.getDebitorRelUuid()); debitorRelOptional.ifPresentOrElse( - debitorRel -> {entityToSave.setDebitorRel(relrealRepo.save(debitorRel));}, + debitorRel -> {entityToSave.setDebitorRel(realRelRepo.save(debitorRel));}, () -> { throw new ValidationException( "Unable to find RealRelation by debitorRelUuid: " + body.getDebitorRelUuid()); @@ -107,7 +111,7 @@ public class HsOfficeDebitorController implements HsOfficeDebitorsApi { } final var savedEntity = debitorRepo.save(entityToSave); - em.flush(); + em.flush(); // FIXME: necessary? em.refresh(savedEntity); final var uri = @@ -191,6 +195,14 @@ public class HsOfficeDebitorController implements HsOfficeDebitorsApi { return ResponseEntity.ok(mapped); } + final BiConsumer RESOURCE_TO_ENTITY_POSTMAPPER = (resource, entity) -> { + if (resource.getRefundBankAccountUuid() != null) { + final var bankAccountEntity = bankAccountRepo.findByUuid(resource.getRefundBankAccountUuid()) + .orElseThrow(() -> new ValidationException()); // FIXME + entity.setRefundBankAccount(bankAccountEntity); + } + }; + final BiConsumer ENTITY_TO_RESOURCE_POSTMAPPER = (entity, resource) -> { resource.setDebitorNumber(entity.getTaggedDebitorNumber()); }; 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 43cc292d..778d12b9 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 @@ -7,13 +7,15 @@ import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeMember import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeMembershipPatchResource; import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeMembershipResource; import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerEntity; -import net.hostsharing.hsadminng.mapper.StandardMapper; +import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerRepository; +import net.hostsharing.hsadminng.mapper.StrictMapper; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.ResponseEntity; import org.springframework.transaction.annotation.Transactional; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.servlet.mvc.method.annotation.MvcUriComponentsBuilder; +import jakarta.persistence.EntityNotFoundException; import java.util.List; import java.util.UUID; import java.util.function.BiConsumer; @@ -28,7 +30,10 @@ public class HsOfficeMembershipController implements HsOfficeMembershipsApi { private Context context; @Autowired - private StandardMapper mapper; + private StrictMapper mapper; + + @Autowired + private HsOfficePartnerRepository partnerRepo; @Autowired private HsOfficeMembershipRepository membershipRepo; @@ -68,7 +73,7 @@ public class HsOfficeMembershipController implements HsOfficeMembershipsApi { context.define(currentSubject, assumedRoles); - final var entityToSave = mapper.map(body, HsOfficeMembershipEntity.class); + final var entityToSave = mapper.map(body, HsOfficeMembershipEntity.class, SEPA_MANDATE_RESOURCE_TO_ENTITY_POSTMAPPER); final var saved = membershipRepo.save(entityToSave); @@ -164,5 +169,12 @@ public class HsOfficeMembershipController implements HsOfficeMembershipsApi { if (entity.getValidity().hasUpperBound()) { resource.setValidTo(entity.getValidity().upper().minusDays(1)); } + resource.getPartner().setPartnerNumber(entity.getPartner().getTaggedPartnerNumber()); // FIXME: use partner mapper? + }; + + final BiConsumer SEPA_MANDATE_RESOURCE_TO_ENTITY_POSTMAPPER = (resource, entity) -> { + entity.setPartner(partnerRepo.findByUuid(resource.getPartnerUuid()) + .orElseThrow(() -> new EntityNotFoundException( + "ERROR: [400] partnerUuid %s not found".formatted(resource.getPartnerUuid())))); }; } diff --git a/src/main/java/net/hostsharing/hsadminng/hs/office/membership/HsOfficeMembershipEntityPatcher.java b/src/main/java/net/hostsharing/hsadminng/hs/office/membership/HsOfficeMembershipEntityPatcher.java index 33bf363b..79bfb340 100644 --- a/src/main/java/net/hostsharing/hsadminng/hs/office/membership/HsOfficeMembershipEntityPatcher.java +++ b/src/main/java/net/hostsharing/hsadminng/hs/office/membership/HsOfficeMembershipEntityPatcher.java @@ -2,18 +2,18 @@ package net.hostsharing.hsadminng.hs.office.membership; import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeMembershipPatchResource; import net.hostsharing.hsadminng.mapper.EntityPatcher; -import net.hostsharing.hsadminng.mapper.StandardMapper; import net.hostsharing.hsadminng.mapper.OptionalFromJson; +import net.hostsharing.hsadminng.mapper.StrictMapper; import java.util.Optional; public class HsOfficeMembershipEntityPatcher implements EntityPatcher { - private final StandardMapper mapper; + private final StrictMapper mapper; private final HsOfficeMembershipEntity entity; public HsOfficeMembershipEntityPatcher( - final StandardMapper mapper, + final StrictMapper mapper, final HsOfficeMembershipEntity entity) { this.mapper = mapper; this.entity = entity; diff --git a/src/main/java/net/hostsharing/hsadminng/hs/office/partner/HsOfficePartnerRepository.java b/src/main/java/net/hostsharing/hsadminng/hs/office/partner/HsOfficePartnerRepository.java index 3ae4a26a..7715d011 100644 --- a/src/main/java/net/hostsharing/hsadminng/hs/office/partner/HsOfficePartnerRepository.java +++ b/src/main/java/net/hostsharing/hsadminng/hs/office/partner/HsOfficePartnerRepository.java @@ -16,18 +16,33 @@ public interface HsOfficePartnerRepository extends Repository findAll(); // TODO.refa: move to a repo in test sources - @Query(""" - SELECT partner FROM HsOfficePartnerEntity partner - JOIN HsOfficeRelationRealEntity rel ON rel.uuid = partner.partnerRel.uuid - JOIN HsOfficeContactRealEntity contact ON contact.uuid = rel.contact.uuid - JOIN HsOfficePersonRealEntity person ON person.uuid = rel.holder.uuid - WHERE :name is null - OR partner.details.birthName like concat(cast(:name as text), '%') - OR contact.caption like concat(cast(:name as text), '%') - OR person.tradeName like concat(cast(:name as text), '%') - OR person.givenName like concat(cast(:name as text), '%') - OR person.familyName like concat(cast(:name as text), '%') - """) +// @Query(""" +// SELECT partner FROM HsOfficePartnerEntity partner +// JOIN HsOfficeRelationRealEntity rel ON rel.uuid = partner.partnerRel.uuid +// JOIN HsOfficeContactRealEntity contact ON contact.uuid = rel.contact.uuid +// JOIN HsOfficePersonRealEntity person ON person.uuid = rel.holder.uuid +// LEFT JOIN HsOfficePartnerDetailsEntity details ON partner.details.uuid = details.uuid +// WHERE :name is null +// OR (details IS NOT NULL AND details.birthName like concat(cast(:name as text), '%')) +// OR contact.caption like concat(cast(:name as text), '%') +// OR person.tradeName like concat(cast(:name as text), '%') +// OR person.givenName like concat(cast(:name as text), '%') +// OR person.familyName like concat(cast(:name as text), '%') +// """) + @Query(value = """ + select partner.uuid, partner.detailsuuid, partner.partnernumber, partner.partnerreluuid, partner.version + from hs_office.partner_rv partner + join hs_office.relation partnerRel on partnerRel.uuid = partner.partnerreluuid + join hs_office.contact contact on contact.uuid = partnerRel.contactuuid + join hs_office.person partnerPerson on partnerPerson.uuid = partnerRel.holderuuid + left join hs_office.partner_details_rv partnerDetails on partnerDetails.uuid = partner.detailsuuid + where :name is null + or (partnerDetails.uuid is not null and partnerDetails.birthname like (cast(:name as text) || '%') escape '') + or contact.caption like (cast(:name as text) || '%') escape '' + or partnerPerson.tradename like (cast(:name as text) || '%') escape '' + or partnerPerson.givenname like (cast(:name as text) || '%') escape '' + or partnerPerson.familyname like (cast(:name as text) || '%') escape '' + """, nativeQuery = true) @Timed("app.office.partners.repo.findPartnerByOptionalNameLike") List findPartnerByOptionalNameLike(String name); diff --git a/src/main/java/net/hostsharing/hsadminng/hs/office/person/HsOfficePersonRealEntity.java b/src/main/java/net/hostsharing/hsadminng/hs/office/person/HsOfficePersonRealEntity.java index 766785a0..0d320d07 100644 --- a/src/main/java/net/hostsharing/hsadminng/hs/office/person/HsOfficePersonRealEntity.java +++ b/src/main/java/net/hostsharing/hsadminng/hs/office/person/HsOfficePersonRealEntity.java @@ -3,7 +3,6 @@ package net.hostsharing.hsadminng.hs.office.person; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; -import lombok.experimental.FieldNameConstants; import lombok.experimental.SuperBuilder; import net.hostsharing.hsadminng.errors.DisplayAs; @@ -17,7 +16,6 @@ import jakarta.persistence.Table; @Setter @NoArgsConstructor @SuperBuilder(toBuilder = true) -@FieldNameConstants @DisplayAs("RealPerson") public class HsOfficePersonRealEntity extends HsOfficePerson { } 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 02a3beb4..61399d1e 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 @@ -2,11 +2,14 @@ package net.hostsharing.hsadminng.hs.office.sepamandate; import io.micrometer.core.annotation.Timed; 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.hsadminng.hs.office.generated.api.v1.api.HsOfficeSepaMandatesApi; +import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeDebitorResource; 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.StandardMapper; +import net.hostsharing.hsadminng.mapper.StrictMapper; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.ResponseEntity; import org.springframework.transaction.annotation.Transactional; @@ -15,6 +18,7 @@ import org.springframework.web.servlet.mvc.method.annotation.MvcUriComponentsBui import jakarta.persistence.EntityManager; import jakarta.persistence.PersistenceContext; +import jakarta.validation.ValidationException; import java.util.List; import java.util.UUID; import java.util.function.BiConsumer; @@ -29,7 +33,13 @@ public class HsOfficeSepaMandateController implements HsOfficeSepaMandatesApi { private Context context; @Autowired - private StandardMapper mapper; + private StrictMapper mapper; + + @Autowired + private HsOfficeDebitorRepository debitorRepo; + + @Autowired + private HsOfficeBankAccountRepository bankAccountRepo; @Autowired private HsOfficeSepaMandateRepository sepaMandateRepo; @@ -137,10 +147,22 @@ public class HsOfficeSepaMandateController implements HsOfficeSepaMandatesApi { if (entity.getValidity().hasUpperBound()) { resource.setValidTo(entity.getValidity().upper().minusDays(1)); } + resource.setDebitor(mapper.map(entity.getDebitor(), HsOfficeDebitorResource.class)); resource.getDebitor().setDebitorNumber(entity.getDebitor().getTaggedDebitorNumber()); + resource.getDebitor().getPartner().setPartnerNumber(entity.getDebitor().getPartner().getTaggedPartnerNumber()); }; final BiConsumer SEPA_MANDATE_RESOURCE_TO_ENTITY_POSTMAPPER = (resource, entity) -> { entity.setValidity(toPostgresDateRange(resource.getValidFrom(), resource.getValidTo())); + entity.setDebitor(debitorRepo.findByUuid(resource.getDebitorUuid()).orElseThrow( () -> + new ValidationException( + "debitor.uuid='" + resource.getDebitorUuid() + "' not found or not accessible" + ) + )); + entity.setBankAccount(bankAccountRepo.findByUuid(resource.getBankAccountUuid()).orElseThrow( () -> + new ValidationException( + "bankAccount.uuid='" + resource.getBankAccountUuid() + "' not found or not accessible" + ) + )); }; } diff --git a/src/main/resources/api-definition/hs-office/hs-office-debitor-schemas.yaml b/src/main/resources/api-definition/hs-office/hs-office-debitor-schemas.yaml index c868a459..9b115889 100644 --- a/src/main/resources/api-definition/hs-office/hs-office-debitor-schemas.yaml +++ b/src/main/resources/api-definition/hs-office/hs-office-debitor-schemas.yaml @@ -90,6 +90,7 @@ components: type: boolean vatReverseCharge: type: boolean + # TODO.feat: alternatively the complete refundBankAccount refundBankAccount.uuid: type: string format: uuid 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 a4b19eef..48d12f44 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 @@ -374,7 +374,6 @@ class HsOfficeContactControllerAcceptanceTest extends ContextBasedTestWithCleanu return jpaAttempt.transacted(() -> { context.define(creatingUser); final var newContact = HsOfficeContactRbacEntity.builder() - .uuid(UUID.randomUUID()) .caption("Temp from " + Context.getCallerMethodNameFromStackFrame(1) ) .postalAddress(Map.ofEntries( entry("name", RandomStringUtils.randomAlphabetic(6) + " " + RandomStringUtils.randomAlphabetic(10)), diff --git a/src/test/java/net/hostsharing/hsadminng/hs/office/coopshares/HsOfficeCoopSharesTransactionControllerAcceptanceTest.java b/src/test/java/net/hostsharing/hsadminng/hs/office/coopshares/HsOfficeCoopSharesTransactionControllerAcceptanceTest.java index 5568fa2f..55411a10 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/office/coopshares/HsOfficeCoopSharesTransactionControllerAcceptanceTest.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/office/coopshares/HsOfficeCoopSharesTransactionControllerAcceptanceTest.java @@ -197,7 +197,7 @@ class HsOfficeCoopSharesTransactionControllerAcceptanceTest extends ContextBased @Test void globalAdmin_canAddCoopSharesReversalTransaction() { - context.define("superuser-alex@hostsharing.net"); + context.define("superuser-alex@hostsharing.net", "global#global:ADMIN"); final var givenMembership = membershipRepo.findMembershipByMemberNumber(1000101).orElseThrow(); final var givenTransaction = jpaAttempt.transacted(() -> { // TODO.impl: introduce something like transactedAsSuperuser / transactedAs("...", ...) @@ -214,46 +214,46 @@ class HsOfficeCoopSharesTransactionControllerAcceptanceTest extends ContextBased final var location = RestAssured // @formatter:off .given() - .header("current-subject", "superuser-alex@hostsharing.net") - .contentType(ContentType.JSON) - .body(""" - { - "membership.uuid": "%s", - "transactionType": "REVERSAL", - "shareCount": %s, - "valueDate": "2022-10-30", - "reference": "test reversal ref", - "comment": "some coop shares reversal transaction", - "revertedShareTx.uuid": "%s" - } - """.formatted( - givenMembership.getUuid(), - -givenTransaction.getShareCount(), - givenTransaction.getUuid())) - .port(port) + .header("current-subject", "superuser-alex@hostsharing.net") + .contentType(ContentType.JSON) + .body(""" + { + "membership.uuid": "%s", + "transactionType": "REVERSAL", + "shareCount": %s, + "valueDate": "2022-10-30", + "reference": "test reversal ref", + "comment": "some coop shares reversal transaction", + "revertedShareTx.uuid": "%s" + } + """.formatted( + givenMembership.getUuid(), + -givenTransaction.getShareCount(), + givenTransaction.getUuid())) + .port(port) .when() - .post("http://localhost/api/hs/office/coopsharestransactions") + .post("http://localhost/api/hs/office/coopsharestransactions") .then().log().all().assertThat() - .statusCode(201) - .contentType(ContentType.JSON) - .body("uuid", isUuidValid()) - .body("", lenientlyEquals(""" - { - "transactionType": "REVERSAL", - "shareCount": -13, - "valueDate": "2022-10-30", - "reference": "test reversal ref", - "comment": "some coop shares reversal transaction", - "revertedShareTx": { - "transactionType": "SUBSCRIPTION", - "shareCount": 13, - "valueDate": "2022-10-20", - "reference": "test ref" - } + .statusCode(201) + .contentType(ContentType.JSON) + .body("uuid", isUuidValid()) + .body("", lenientlyEquals(""" + { + "transactionType": "REVERSAL", + "shareCount": -13, + "valueDate": "2022-10-30", + "reference": "test reversal ref", + "comment": "some coop shares reversal transaction", + "revertedShareTx": { + "transactionType": "SUBSCRIPTION", + "shareCount": 13, + "valueDate": "2022-10-20", + "reference": "test ref" } - """)) - .header("Location", startsWith("http://localhost")) - .extract().header("Location"); // @formatter:on + } + """)) + .header("Location", startsWith("http://localhost")) + .extract().header("Location"); // @formatter:on // finally, the new coopAssetsTransaction can be accessed under the generated UUID final var newShareTxUuid = UUID.fromString( @@ -269,22 +269,34 @@ class HsOfficeCoopSharesTransactionControllerAcceptanceTest extends ContextBased final var givenMembership = membershipRepo.findMembershipByMemberNumber(1000101).orElseThrow(); RestAssured // @formatter:off - .given().header("current-subject", "superuser-alex@hostsharing.net").contentType(ContentType.JSON).body(""" - { - "membership.uuid": "%s", - "transactionType": "CANCELLATION", - "shareCount": -80, - "valueDate": "2022-10-13", - "reference": "temp ref X", - "comment": "just some test coop shares transaction" - } - """.formatted(givenMembership.getUuid())).port(port).when().post("http://localhost/api/hs/office/coopsharestransactions").then().log().all().assertThat().statusCode(400).contentType(ContentType.JSON).body("", lenientlyEquals(""" + .given() + .header("current-subject", "superuser-alex@hostsharing.net") + .contentType(ContentType.JSON) + .body(""" { - "statusCode": 400, - "statusPhrase": "Bad Request", - "message": "ERROR: [400] coop shares transaction would result in a negative number of shares" - } - """)); // @formatter:on + "membership.uuid": "%s", + "transactionType": "CANCELLATION", + "shareCount": -80, + "valueDate": "2022-10-13", + "reference": "temp ref X", + "comment": "just some test coop shares transaction" + } + """.formatted(givenMembership.getUuid())) + .port(port) + .when() + .post("http://localhost/api/hs/office/coopsharestransactions") + .then() + .log().all() + .assertThat() + .statusCode(400) + .contentType(ContentType.JSON) + .body("", lenientlyEquals(""" + { + "statusCode": 400, + "statusPhrase": "Bad Request", + "message": "ERROR: [400] coop shares transaction would result in a negative number of shares" + } + """)); // @formatter:on } } diff --git a/src/test/java/net/hostsharing/hsadminng/hs/office/coopshares/HsOfficeCoopSharesTransactionControllerRestTest.java b/src/test/java/net/hostsharing/hsadminng/hs/office/coopshares/HsOfficeCoopSharesTransactionControllerRestTest.java index 5bc432de..f6ed87ed 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/office/coopshares/HsOfficeCoopSharesTransactionControllerRestTest.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/office/coopshares/HsOfficeCoopSharesTransactionControllerRestTest.java @@ -1,7 +1,7 @@ package net.hostsharing.hsadminng.hs.office.coopshares; import net.hostsharing.hsadminng.context.Context; -import net.hostsharing.hsadminng.mapper.StandardMapper; +import net.hostsharing.hsadminng.mapper.StrictMapper; import net.hostsharing.hsadminng.rbac.test.JsonBuilder; import net.hostsharing.hsadminng.config.DisableSecurityConfig; import org.junit.jupiter.params.ParameterizedTest; @@ -36,7 +36,7 @@ class HsOfficeCoopSharesTransactionControllerRestTest { @MockBean @SuppressWarnings("unused") // not used in test, but in controller class - StandardMapper mapper; + StrictMapper mapper; @MockBean HsOfficeCoopSharesTransactionRepository coopSharesTransactionRepo; diff --git a/src/test/java/net/hostsharing/hsadminng/hs/office/membership/HsOfficeMembershipControllerAcceptanceTest.java b/src/test/java/net/hostsharing/hsadminng/hs/office/membership/HsOfficeMembershipControllerAcceptanceTest.java index 88f29868..3c67b2cd 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/office/membership/HsOfficeMembershipControllerAcceptanceTest.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/office/membership/HsOfficeMembershipControllerAcceptanceTest.java @@ -430,7 +430,6 @@ class HsOfficeMembershipControllerAcceptanceTest extends ContextBasedTestWithCle context.define("superuser-alex@hostsharing.net"); final var givenPartner = partnerRepo.findPartnerByOptionalNameLike(partnerName).get(0); final var newMembership = HsOfficeMembershipEntity.builder() - .uuid(UUID.randomUUID()) .partner(givenPartner) .memberNumberSuffix(TEMP_MEMBER_NUMBER_SUFFIX) .validity(Range.closedInfinite(LocalDate.parse("2022-11-01"))) diff --git a/src/test/java/net/hostsharing/hsadminng/hs/office/membership/HsOfficeMembershipEntityPatcherUnitTest.java b/src/test/java/net/hostsharing/hsadminng/hs/office/membership/HsOfficeMembershipEntityPatcherUnitTest.java index f6ab56fa..e5ffccfe 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/office/membership/HsOfficeMembershipEntityPatcherUnitTest.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/office/membership/HsOfficeMembershipEntityPatcherUnitTest.java @@ -4,7 +4,7 @@ import io.hypersistence.utils.hibernate.type.range.Range; import net.hostsharing.hsadminng.hs.office.debitor.HsOfficeDebitorEntity; import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeMembershipPatchResource; import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeMembershipStatusResource; -import net.hostsharing.hsadminng.mapper.StandardMapper; +import net.hostsharing.hsadminng.mapper.StrictMapper; import net.hostsharing.hsadminng.persistence.EntityManagerWrapper; import net.hostsharing.hsadminng.rbac.test.PatchUnitTestBase; import org.junit.jupiter.api.BeforeEach; @@ -40,7 +40,7 @@ class HsOfficeMembershipEntityPatcherUnitTest extends PatchUnitTestBase< @Mock private EntityManagerWrapper em; - private StandardMapper mapper = new StandardMapper(em); + private StrictMapper mapper = new StrictMapper(em); @BeforeEach void initMocks() { 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 c8a709a1..1ce4df3d 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 @@ -16,7 +16,7 @@ import org.junit.jupiter.api.Nested; 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.boot.test.mock.mockito.MockBean; // FIXME: use MockitoBean import org.springframework.context.annotation.Import; import org.springframework.orm.jpa.JpaSystemException; @@ -32,6 +32,7 @@ import static net.hostsharing.hsadminng.rbac.role.RawRbacObjectEntity.objectDisp import static net.hostsharing.hsadminng.rbac.role.RawRbacRoleEntity.distinctRoleNamesOf; import static net.hostsharing.hsadminng.mapper.Array.from; import static net.hostsharing.hsadminng.rbac.role.RbacRoleType.ADMIN; +import static net.hostsharing.hsadminng.rbac.role.RbacRoleType.AGENT; import static net.hostsharing.hsadminng.rbac.test.JpaAttempt.attempt; import static org.assertj.core.api.Assertions.assertThat; @@ -207,9 +208,23 @@ class HsOfficePartnerRepositoryIntegrationTest extends ContextBasedTestWithClean } @Test - public void normalUser_canViewOnlyRelatedPartners() { + public void partnerAgent_canViewOnlyRelatedPartnersWithoutDetails() { // given: - context("person-FirstGmbH@example.com"); + context("person-FirstGmbH@example.com", + "hs_office.relation#HostsharingeG-with-PARTNER-FirstGmbH:AGENT"); + + // when: + final var result = partnerRepo.findPartnerByOptionalNameLike(null); + + // then: + exactlyThesePartnersAreReturned(result, "partner(P-10001: LP First GmbH, first contact)"); + } + + @Test + public void partnerTenant_canViewRelatedPartnersButWithoutDetails() { + // given: + context("person-FirstGmbH@example.com", + "hs_office.relation#HostsharingeG-with-PARTNER-FirstGmbH:TENANT"); // when: final var result = partnerRepo.findPartnerByOptionalNameLike(null); @@ -289,19 +304,19 @@ class HsOfficePartnerRepositoryIntegrationTest extends ContextBasedTestWithClean } @Test - public void partnerRelationAgent_canUpdateRelatedPartner() { + public void partnerRelationAgent_canUpdateRelatedPartnerDetails() { // given context("superuser-alex@hostsharing.net"); final var givenPartner = givenSomeTemporaryHostsharingPartner(20037, "Erben Bessler", "ninth"); assertThatPartnerIsVisibleForUserWithRole( givenPartner, - "hs_office.person#ErbenBesslerMelBessler:ADMIN"); + givenPartner.getPartnerRel().roleId(AGENT)); assertThatPartnerActuallyInDatabase(givenPartner); // when final var result = jpaAttempt.transacted(() -> { context("superuser-alex@hostsharing.net", - "hs_office.person#ErbenBesslerMelBessler:ADMIN"); + givenPartner.getPartnerRel().roleId(AGENT)); givenPartner.getDetails().setBirthName("new birthname"); return partnerRepo.save(givenPartner); }); @@ -310,30 +325,6 @@ class HsOfficePartnerRepositoryIntegrationTest extends ContextBasedTestWithClean result.assertSuccessful(); } - @Test - public void partnerRelationTenant_canNotUpdateRelatedPartner() { - // given - context("superuser-alex@hostsharing.net"); - final var givenPartner = givenSomeTemporaryHostsharingPartner(20037, "Erben Bessler", "ninth"); - assertThatPartnerIsVisibleForUserWithRole( - givenPartner, - "hs_office.person#ErbenBesslerMelBessler:ADMIN"); - assertThatPartnerActuallyInDatabase(givenPartner); - - // when - final var result = jpaAttempt.transacted(() -> { - context("superuser-alex@hostsharing.net", - "hs_office.relation#HostsharingeG-with-PARTNER-ErbenBesslerMelBessler:TENANT"); - givenPartner.getDetails().setBirthName("new birthname"); - return partnerRepo.save(givenPartner); - }); - - // then - result.assertExceptionWithRootCauseMessage(JpaSystemException.class, - "ERROR: [403] insert into hs_office.partner_details ", - " not allowed for current subjects {hs_office.relation#HostsharingeG-with-PARTNER-ErbenBesslerMelBessler:TENANT}"); - } - private void assertThatPartnerActuallyInDatabase(final HsOfficePartnerEntity saved) { final var found = partnerRepo.findByUuid(saved.getUuid()); assertThat(found).isNotEmpty().get().isNotSameAs(saved).extracting(HsOfficePartnerEntity::toString).isEqualTo(saved.toString()); @@ -463,7 +454,10 @@ class HsOfficePartnerRepositoryIntegrationTest extends ContextBasedTestWithClean .details(HsOfficePartnerDetailsEntity.builder().build()) .build(); - return partnerRepo.save(newPartner); + final var savedPartner = partnerRepo.save(newPartner); + em.flush(); + final var partner = em.find(savedPartner.getClass(), savedPartner.getUuid()); + return savedPartner; }).assertSuccessful().returnedValue(); } @@ -484,13 +478,13 @@ class HsOfficePartnerRepositoryIntegrationTest extends ContextBasedTestWithClean void exactlyThesePartnersAreReturned(final List actualResult, final String... partnerNames) { assertThat(actualResult) - .extracting(partnerEntity -> partnerEntity.toString()) + .extracting(HsOfficePartnerEntity::toString) .containsExactlyInAnyOrder(partnerNames); } void allThesePartnersAreReturned(final List actualResult, final String... partnerNames) { assertThat(actualResult) - .extracting(partnerEntity -> partnerEntity.toString()) + .extracting(HsOfficePartnerEntity::toString) .contains(partnerNames); } 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 b0cae150..a2c21dac 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 @@ -331,7 +331,6 @@ class HsOfficePersonControllerAcceptanceTest extends ContextBasedTestWithCleanup return jpaAttempt.transacted(() -> { context.define(creatingUser); final var newPerson = HsOfficePersonRealEntity.builder() - .uuid(UUID.randomUUID()) .personType(HsOfficePersonType.LEGAL_PERSON) .tradeName("Temp " + Context.getCallerMethodNameFromStackFrame(2)) .familyName(RandomStringUtils.randomAlphabetic(10) + "@example.org") 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 eabde5a7..b8876423 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 @@ -180,10 +180,9 @@ class HsOfficeSepaMandateControllerAcceptanceTest extends ContextBasedTestWithCl void globalAdmin_canNotPostNewSepaMandateWhenDebitorUuidIsMissing() { context.define("superuser-alex@hostsharing.net"); - final var givenDebitor = debitorRepo.findDebitorsByOptionalNameLike("Third").get(0); final var givenBankAccount = bankAccountRepo.findByIbanOrderByIbanAsc("DE02200505501015871393").get(0); - final var location = RestAssured // @formatter:off + RestAssured // @formatter:off .given() .header("current-subject", "superuser-alex@hostsharing.net") .contentType(ContentType.JSON) @@ -227,12 +226,12 @@ class HsOfficeSepaMandateControllerAcceptanceTest extends ContextBasedTestWithCl .post("http://localhost/api/hs/office/sepamandates") .then().log().all().assertThat() .statusCode(400) - .body("message", is("ERROR: [400] Unable to find BankAccount with uuid 00000000-0000-0000-0000-000000000000")); + .body("message", is("ERROR: [400] bankAccount.uuid='00000000-0000-0000-0000-000000000000' not found or not accessible")); // @formatter:on } @Test - void globalAdmin_canNotPostNewSepaMandate_ifPersonDoesNotExist() { + void globalAdmin_canNotPostNewSepaMandate_ifDebitorDoesNotExist() { context.define("superuser-alex@hostsharing.net"); final var givenDebitorUuid = UUID.fromString("00000000-0000-0000-0000-000000000000"); @@ -257,7 +256,7 @@ class HsOfficeSepaMandateControllerAcceptanceTest extends ContextBasedTestWithCl .post("http://localhost/api/hs/office/sepamandates") .then().log().all().assertThat() .statusCode(400) - .body("message", is("ERROR: [400] Unable to find Debitor with uuid 00000000-0000-0000-0000-000000000000")); + .body("message", is("ERROR: [400] debitor.uuid='00000000-0000-0000-0000-000000000000' not found or not accessible")); // @formatter:on } } @@ -529,7 +528,6 @@ class HsOfficeSepaMandateControllerAcceptanceTest extends ContextBasedTestWithCl .orElse(givenDebitor.getPartner().getPartnerRel().getHolder().getFamilyName()); final var givenBankAccount = bankAccountRepo.findByOptionalHolderLike(bankAccountHolder).get(0); final var newSepaMandate = HsOfficeSepaMandateEntity.builder() - .uuid(UUID.randomUUID()) .debitor(givenDebitor) .bankAccount(givenBankAccount) .reference("temp ref CAT Z") diff --git a/src/test/resources/application.yml b/src/test/resources/application.yml index 954bdd63..344828e7 100644 --- a/src/test/resources/application.yml +++ b/src/test/resources/application.yml @@ -6,7 +6,7 @@ management: endpoints: web: exposure: - include: info, health, metrics, metric-links + include: info, health, metrics, metric-links, mappings, openapi, swaggerui spring: sql: -- 2.39.5 From 3ff969c38e68a40bc141230be72aaf66cf99b23d Mon Sep 17 00:00:00 2001 From: Michael Hoennig Date: Sun, 12 Jan 2025 13:44:01 +0100 Subject: [PATCH 02/35] re-enabling spring-boot-devtools --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 2ef4a819..39c61aa2 100644 --- a/build.gradle +++ b/build.gradle @@ -79,7 +79,7 @@ dependencies { compileOnly 'org.projectlombok:lombok' testCompileOnly 'org.projectlombok:lombok' - // FIXME: developmentOnly 'org.springframework.boot:spring-boot-devtools' + developmentOnly 'org.springframework.boot:spring-boot-devtools' annotationProcessor 'org.projectlombok:lombok' testAnnotationProcessor 'org.projectlombok:lombok' -- 2.39.5 From 11b894e8eed4953e3c82852cb0eaaf69bd5f19a4 Mon Sep 17 00:00:00 2001 From: Michael Hoennig Date: Sun, 12 Jan 2025 14:29:50 +0100 Subject: [PATCH 03/35] only use StrictMapper --- .../project/HsBookingProjectController.java | 4 ++-- .../hosting/asset/HsHostingAssetController.java | 4 ++-- .../DomainSetupHostingAssetFactory.java | 6 +++--- .../asset/factories/HostingAssetFactory.java | 4 ++-- .../factories/HsBookingItemCreatedListener.java | 14 +++++++------- .../ManagedWebspaceHostingAssetFactory.java | 8 ++++---- .../HsOfficeBankAccountController.java | 4 ++-- .../contact/HsOfficeContactController.java | 4 ++-- .../partner/HsOfficePartnerController.java | 4 ++-- .../office/person/HsOfficePersonController.java | 4 ++-- .../relation/HsOfficeRelationController.java | 4 ++-- .../hsadminng/mapper/StandardMapper.java | 17 ----------------- .../rbac/grant/RbacGrantController.java | 4 ++-- .../hsadminng/rbac/role/RbacRoleController.java | 4 ++-- .../rbac/subject/RbacSubjectController.java | 4 ++-- .../rbac/test/cust/TestCustomerController.java | 4 ++-- .../rbac/test/pac/TestPackageController.java | 4 ++-- .../HsHostingAssetControllerAcceptanceTest.java | 4 ---- .../asset/HsHostingAssetControllerRestTest.java | 6 +++--- .../DomainSetupHostingAssetFactoryUnitTest.java | 4 ++-- .../HsBookingItemCreatedListenerUnitTest.java | 4 ++-- ...agedWebspaceHostingAssetFactoryUnitTest.java | 4 ++-- .../HsOfficeBankAccountControllerRestTest.java | 4 ++-- .../HsOfficeMembershipControllerRestTest.java | 4 ++-- .../HsOfficePartnerControllerRestTest.java | 4 ++-- .../rbac/context/ContextIntegrationTests.java | 4 ++-- .../rbac/role/RbacRoleControllerRestTest.java | 4 ++-- .../subject/RbacSubjectControllerRestTest.java | 4 ++-- .../hsadminng/rbac/test/MapperUnitTest.java | 4 ++-- 29 files changed, 63 insertions(+), 84 deletions(-) delete mode 100644 src/main/java/net/hostsharing/hsadminng/mapper/StandardMapper.java diff --git a/src/main/java/net/hostsharing/hsadminng/hs/booking/project/HsBookingProjectController.java b/src/main/java/net/hostsharing/hsadminng/hs/booking/project/HsBookingProjectController.java index ac21083a..98b856b9 100644 --- a/src/main/java/net/hostsharing/hsadminng/hs/booking/project/HsBookingProjectController.java +++ b/src/main/java/net/hostsharing/hsadminng/hs/booking/project/HsBookingProjectController.java @@ -7,7 +7,7 @@ import net.hostsharing.hsadminng.hs.booking.generated.api.v1.api.HsBookingProjec import net.hostsharing.hsadminng.hs.booking.generated.api.v1.model.HsBookingProjectInsertResource; import net.hostsharing.hsadminng.hs.booking.generated.api.v1.model.HsBookingProjectPatchResource; import net.hostsharing.hsadminng.hs.booking.generated.api.v1.model.HsBookingProjectResource; -import net.hostsharing.hsadminng.mapper.StandardMapper; +import net.hostsharing.hsadminng.mapper.StrictMapper; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.ResponseEntity; import org.springframework.transaction.annotation.Transactional; @@ -26,7 +26,7 @@ public class HsBookingProjectController implements HsBookingProjectsApi { private Context context; @Autowired - private StandardMapper mapper; + private StrictMapper mapper; @Autowired private HsBookingProjectRbacRepository bookingProjectRepo; diff --git a/src/main/java/net/hostsharing/hsadminng/hs/hosting/asset/HsHostingAssetController.java b/src/main/java/net/hostsharing/hsadminng/hs/hosting/asset/HsHostingAssetController.java index a8d4f7cf..f9a45f70 100644 --- a/src/main/java/net/hostsharing/hsadminng/hs/hosting/asset/HsHostingAssetController.java +++ b/src/main/java/net/hostsharing/hsadminng/hs/hosting/asset/HsHostingAssetController.java @@ -12,7 +12,7 @@ import net.hostsharing.hsadminng.hs.hosting.generated.api.v1.model.HsHostingAsse import net.hostsharing.hsadminng.hs.hosting.generated.api.v1.model.HsHostingAssetResource; import net.hostsharing.hsadminng.hs.hosting.generated.api.v1.model.HsHostingAssetTypeResource; import net.hostsharing.hsadminng.mapper.KeyValueMap; -import net.hostsharing.hsadminng.mapper.StandardMapper; +import net.hostsharing.hsadminng.mapper.StrictMapper; import net.hostsharing.hsadminng.persistence.EntityManagerWrapper; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.ResponseEntity; @@ -36,7 +36,7 @@ public class HsHostingAssetController implements HsHostingAssetsApi { private Context context; @Autowired - private StandardMapper mapper; + private StrictMapper mapper; @Autowired private HsHostingAssetRbacRepository rbacAssetRepo; diff --git a/src/main/java/net/hostsharing/hsadminng/hs/hosting/asset/factories/DomainSetupHostingAssetFactory.java b/src/main/java/net/hostsharing/hsadminng/hs/hosting/asset/factories/DomainSetupHostingAssetFactory.java index 00a8c4d4..812c81a9 100644 --- a/src/main/java/net/hostsharing/hsadminng/hs/hosting/asset/factories/DomainSetupHostingAssetFactory.java +++ b/src/main/java/net/hostsharing/hsadminng/hs/hosting/asset/factories/DomainSetupHostingAssetFactory.java @@ -9,7 +9,7 @@ import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetRealEntity; import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType; import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactRealEntity; import net.hostsharing.hsadminng.lambda.Reducer; -import net.hostsharing.hsadminng.mapper.StandardMapper; +import net.hostsharing.hsadminng.mapper.StrictMapper; import net.hostsharing.hsadminng.mapper.ToStringConverter; import net.hostsharing.hsadminng.persistence.EntityManagerWrapper; @@ -31,8 +31,8 @@ public class DomainSetupHostingAssetFactory extends HostingAssetFactory { final EntityManagerWrapper emw, final HsBookingItemRealEntity newBookingItemRealEntity, final HsHostingAssetAutoInsertResource asset, - final StandardMapper standardMapper) { - super(emw, newBookingItemRealEntity, asset, standardMapper); + final StrictMapper StrictMapper) { + super(emw, newBookingItemRealEntity, asset, StrictMapper); } @Override diff --git a/src/main/java/net/hostsharing/hsadminng/hs/hosting/asset/factories/HostingAssetFactory.java b/src/main/java/net/hostsharing/hsadminng/hs/hosting/asset/factories/HostingAssetFactory.java index 392fe1e6..290f40ec 100644 --- a/src/main/java/net/hostsharing/hsadminng/hs/hosting/asset/factories/HostingAssetFactory.java +++ b/src/main/java/net/hostsharing/hsadminng/hs/hosting/asset/factories/HostingAssetFactory.java @@ -6,7 +6,7 @@ import net.hostsharing.hsadminng.hs.booking.generated.api.v1.model.HsHostingAsse import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemRealEntity; import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAsset; import net.hostsharing.hsadminng.hs.hosting.asset.validators.HostingAssetEntitySaveProcessor; -import net.hostsharing.hsadminng.mapper.StandardMapper; +import net.hostsharing.hsadminng.mapper.StrictMapper; import net.hostsharing.hsadminng.persistence.EntityManagerWrapper; @@ -16,7 +16,7 @@ abstract class HostingAssetFactory { final EntityManagerWrapper emw; final HsBookingItemRealEntity fromBookingItem; final HsHostingAssetAutoInsertResource asset; - final StandardMapper standardMapper; + final StrictMapper StrictMapper; protected abstract HsHostingAsset create(); diff --git a/src/main/java/net/hostsharing/hsadminng/hs/hosting/asset/factories/HsBookingItemCreatedListener.java b/src/main/java/net/hostsharing/hsadminng/hs/hosting/asset/factories/HsBookingItemCreatedListener.java index 8818cef8..73291368 100644 --- a/src/main/java/net/hostsharing/hsadminng/hs/hosting/asset/factories/HsBookingItemCreatedListener.java +++ b/src/main/java/net/hostsharing/hsadminng/hs/hosting/asset/factories/HsBookingItemCreatedListener.java @@ -9,7 +9,7 @@ import net.hostsharing.hsadminng.hs.booking.generated.api.v1.model.HsHostingAsse import net.hostsharing.hsadminng.hs.booking.item.BookingItemCreatedAppEvent; import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemRealEntity; import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAsset; -import net.hostsharing.hsadminng.mapper.StandardMapper; +import net.hostsharing.hsadminng.mapper.StrictMapper; import net.hostsharing.hsadminng.persistence.EntityManagerWrapper; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationListener; @@ -25,7 +25,7 @@ public class HsBookingItemCreatedListener implements ApplicationListener - forNowNoAutomaticHostingAssetCreationPossible(emw, newBookingItemRealEntity, asset, standardMapper); - case MANAGED_WEBSPACE -> new ManagedWebspaceHostingAssetFactory(emw, newBookingItemRealEntity, asset, standardMapper); - case DOMAIN_SETUP -> new DomainSetupHostingAssetFactory(emw, newBookingItemRealEntity, asset, standardMapper); + forNowNoAutomaticHostingAssetCreationPossible(emw, newBookingItemRealEntity, asset, StrictMapper); + case MANAGED_WEBSPACE -> new ManagedWebspaceHostingAssetFactory(emw, newBookingItemRealEntity, asset, StrictMapper); + case DOMAIN_SETUP -> new DomainSetupHostingAssetFactory(emw, newBookingItemRealEntity, asset, StrictMapper); }; if (factory != null) { final var statusMessage = factory.createAndPersist(); @@ -62,9 +62,9 @@ public class HsBookingItemCreatedListener implements ApplicationListener HsHostingAssetRealEntity.builder() - .uuid(UUID.randomUUID()) .bookingItem(givenSomeNewBookingItem( "D-1000111 default project", HsBookingItemType.MANAGED_SERVER, @@ -571,7 +570,6 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup final var givenAsset = givenSomeTemporaryHostingAsset(() -> HsHostingAssetRealEntity.builder() - .uuid(UUID.randomUUID()) .type(UNIX_USER) .parentAsset(givenRealHostingAsset(MANAGED_WEBSPACE, "fir01")) .identifier("fir01-temp") @@ -648,7 +646,6 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup context.define("superuser-alex@hostsharing.net"); final var givenAsset = givenSomeTemporaryHostingAsset(() -> HsHostingAssetRealEntity.builder() - .uuid(UUID.randomUUID()) .bookingItem(givenSomeNewBookingItem( "D-1000111 default project", HsBookingItemType.MANAGED_SERVER, @@ -681,7 +678,6 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup context.define("superuser-alex@hostsharing.net"); final var givenAsset = givenSomeTemporaryHostingAsset(() -> HsHostingAssetRealEntity.builder() - .uuid(UUID.randomUUID()) .bookingItem(givenSomeNewBookingItem( "D-1000111 default project", HsBookingItemType.MANAGED_SERVER, diff --git a/src/test/java/net/hostsharing/hsadminng/hs/hosting/asset/HsHostingAssetControllerRestTest.java b/src/test/java/net/hostsharing/hsadminng/hs/hosting/asset/HsHostingAssetControllerRestTest.java index be1eaef9..6d5f149e 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/hosting/asset/HsHostingAssetControllerRestTest.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/hosting/asset/HsHostingAssetControllerRestTest.java @@ -9,7 +9,7 @@ import net.hostsharing.hsadminng.config.JsonObjectMapperConfiguration; import net.hostsharing.hsadminng.context.Context; import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemRealRepository; import net.hostsharing.hsadminng.mapper.Array; -import net.hostsharing.hsadminng.mapper.StandardMapper; +import net.hostsharing.hsadminng.mapper.StrictMapper; import net.hostsharing.hsadminng.persistence.EntityManagerWrapper; import net.hostsharing.hsadminng.config.DisableSecurityConfig; import org.junit.jupiter.api.BeforeEach; @@ -54,7 +54,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; @WebMvcTest(HsHostingAssetController.class) -@Import({ StandardMapper.class, JsonObjectMapperConfiguration.class, DisableSecurityConfig.class }) +@Import({ StrictMapper.class, JsonObjectMapperConfiguration.class, DisableSecurityConfig.class }) @RunWith(SpringRunner.class) @ActiveProfiles("test") public class HsHostingAssetControllerRestTest { @@ -67,7 +67,7 @@ public class HsHostingAssetControllerRestTest { @Autowired @SuppressWarnings("unused") // not used in test, but in controller class - StandardMapper mapper; + StrictMapper mapper; @MockBean EntityManagerWrapper em; diff --git a/src/test/java/net/hostsharing/hsadminng/hs/hosting/asset/factories/DomainSetupHostingAssetFactoryUnitTest.java b/src/test/java/net/hostsharing/hsadminng/hs/hosting/asset/factories/DomainSetupHostingAssetFactoryUnitTest.java index cf2fc350..fb2e622e 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/hosting/asset/factories/DomainSetupHostingAssetFactoryUnitTest.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/hosting/asset/factories/DomainSetupHostingAssetFactoryUnitTest.java @@ -12,7 +12,7 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import com.fasterxml.jackson.databind.ObjectMapper; import net.hostsharing.hsadminng.config.JsonObjectMapperConfiguration; -import net.hostsharing.hsadminng.mapper.StandardMapper; +import net.hostsharing.hsadminng.mapper.StrictMapper; import net.hostsharing.hsadminng.persistence.EntityManagerWrapper; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.InjectMocks; @@ -59,7 +59,7 @@ class DomainSetupHostingAssetFactoryUnitTest { private ObjectMapper jsonMapper = new JsonObjectMapperConfiguration().customObjectMapper().build(); @Spy - private StandardMapper standardMapper = new StandardMapper(emw); + private StrictMapper StrictMapper = new StrictMapper(emw); @InjectMocks private HsBookingItemCreatedListener listener; diff --git a/src/test/java/net/hostsharing/hsadminng/hs/hosting/asset/factories/HsBookingItemCreatedListenerUnitTest.java b/src/test/java/net/hostsharing/hsadminng/hs/hosting/asset/factories/HsBookingItemCreatedListenerUnitTest.java index 07442a71..63af1b78 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/hosting/asset/factories/HsBookingItemCreatedListenerUnitTest.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/hosting/asset/factories/HsBookingItemCreatedListenerUnitTest.java @@ -8,7 +8,7 @@ import net.hostsharing.hsadminng.hs.booking.item.BookingItemCreatedEventEntity; import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemRealEntity; import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemType; import net.hostsharing.hsadminng.lambda.Reducer; -import net.hostsharing.hsadminng.mapper.StandardMapper; +import net.hostsharing.hsadminng.mapper.StrictMapper; import net.hostsharing.hsadminng.persistence.EntityManagerWrapper; import net.hostsharing.hsadminng.persistence.EntityManagerWrapperFake; import org.junit.jupiter.api.extension.ExtendWith; @@ -42,7 +42,7 @@ class HsBookingItemCreatedListenerUnitTest { private ObjectMapper jsonMapper = new JsonObjectMapperConfiguration().customObjectMapper().build(); @Spy - private StandardMapper standardMapper = new StandardMapper(emw); + private StrictMapper StrictMapper = new StrictMapper(emw); @InjectMocks private HsBookingItemCreatedListener listener; diff --git a/src/test/java/net/hostsharing/hsadminng/hs/hosting/asset/factories/ManagedWebspaceHostingAssetFactoryUnitTest.java b/src/test/java/net/hostsharing/hsadminng/hs/hosting/asset/factories/ManagedWebspaceHostingAssetFactoryUnitTest.java index 511e408c..758dc5e2 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/hosting/asset/factories/ManagedWebspaceHostingAssetFactoryUnitTest.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/hosting/asset/factories/ManagedWebspaceHostingAssetFactoryUnitTest.java @@ -13,7 +13,7 @@ import net.hostsharing.hsadminng.hs.hosting.asset.validators.Dns; import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContact; import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactRealEntity; import net.hostsharing.hsadminng.lambda.Reducer; -import net.hostsharing.hsadminng.mapper.StandardMapper; +import net.hostsharing.hsadminng.mapper.StrictMapper; import net.hostsharing.hsadminng.persistence.EntityManagerWrapper; import net.hostsharing.hsadminng.persistence.EntityManagerWrapperFake; import org.junit.jupiter.api.BeforeEach; @@ -55,7 +55,7 @@ class ManagedWebspaceHostingAssetFactoryUnitTest { private ObjectMapper jsonMapper = new JsonObjectMapperConfiguration().customObjectMapper().build(); @Spy - private StandardMapper standardMapper = new StandardMapper(emw); + private StrictMapper StrictMapper = new StrictMapper(emw); @InjectMocks private HsBookingItemCreatedListener listener; diff --git a/src/test/java/net/hostsharing/hsadminng/hs/office/bankaccount/HsOfficeBankAccountControllerRestTest.java b/src/test/java/net/hostsharing/hsadminng/hs/office/bankaccount/HsOfficeBankAccountControllerRestTest.java index a83558d6..06010ce1 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/office/bankaccount/HsOfficeBankAccountControllerRestTest.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/office/bankaccount/HsOfficeBankAccountControllerRestTest.java @@ -1,7 +1,7 @@ package net.hostsharing.hsadminng.hs.office.bankaccount; import net.hostsharing.hsadminng.context.Context; -import net.hostsharing.hsadminng.mapper.StandardMapper; +import net.hostsharing.hsadminng.mapper.StrictMapper; import net.hostsharing.hsadminng.config.DisableSecurityConfig; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.EnumSource; @@ -31,7 +31,7 @@ class HsOfficeBankAccountControllerRestTest { @MockBean @SuppressWarnings("unused") // not used in test, but in controller class - StandardMapper mapper; + StrictMapper mapper; @MockBean HsOfficeBankAccountRepository bankAccountRepo; 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 58271f57..5cbb4f5f 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 @@ -3,7 +3,7 @@ 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.partner.HsOfficePartnerEntity; -import net.hostsharing.hsadminng.mapper.StandardMapper; +import net.hostsharing.hsadminng.mapper.StrictMapper; import net.hostsharing.hsadminng.persistence.EntityManagerWrapper; import net.hostsharing.hsadminng.config.DisableSecurityConfig; import org.junit.jupiter.api.Nested; @@ -34,7 +34,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; @WebMvcTest(HsOfficeMembershipController.class) -@Import({StandardMapper.class, DisableSecurityConfig.class}) +@Import({StrictMapper.class, DisableSecurityConfig.class}) @ActiveProfiles("test") public class HsOfficeMembershipControllerRestTest { diff --git a/src/test/java/net/hostsharing/hsadminng/hs/office/partner/HsOfficePartnerControllerRestTest.java b/src/test/java/net/hostsharing/hsadminng/hs/office/partner/HsOfficePartnerControllerRestTest.java index 100d3852..44a7c4b3 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/office/partner/HsOfficePartnerControllerRestTest.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/office/partner/HsOfficePartnerControllerRestTest.java @@ -5,7 +5,7 @@ import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactRbacEntity; import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonRealEntity; import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationRealEntity; import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationRealRepository; -import net.hostsharing.hsadminng.mapper.StandardMapper; +import net.hostsharing.hsadminng.mapper.StrictMapper; import net.hostsharing.hsadminng.persistence.EntityManagerWrapper; import net.hostsharing.hsadminng.config.DisableSecurityConfig; import org.junit.jupiter.api.BeforeEach; @@ -38,7 +38,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; @WebMvcTest(HsOfficePartnerController.class) -@Import({StandardMapper.class, DisableSecurityConfig.class}) +@Import({StrictMapper.class, DisableSecurityConfig.class}) @ActiveProfiles("test") class HsOfficePartnerControllerRestTest { diff --git a/src/test/java/net/hostsharing/hsadminng/rbac/context/ContextIntegrationTests.java b/src/test/java/net/hostsharing/hsadminng/rbac/context/ContextIntegrationTests.java index 25d04156..d0f6df12 100644 --- a/src/test/java/net/hostsharing/hsadminng/rbac/context/ContextIntegrationTests.java +++ b/src/test/java/net/hostsharing/hsadminng/rbac/context/ContextIntegrationTests.java @@ -2,7 +2,7 @@ package net.hostsharing.hsadminng.rbac.context; import net.hostsharing.hsadminng.context.Context; import net.hostsharing.hsadminng.mapper.Array; -import net.hostsharing.hsadminng.mapper.StandardMapper; +import net.hostsharing.hsadminng.mapper.StrictMapper; import net.hostsharing.hsadminng.persistence.EntityManagerWrapper; import net.hostsharing.hsadminng.rbac.test.JpaAttempt; import org.junit.jupiter.api.Test; @@ -20,7 +20,7 @@ import jakarta.servlet.http.HttpServletRequest; import static org.assertj.core.api.Assertions.assertThat; @DataJpaTest -@ComponentScan(basePackageClasses = { Context.class, JpaAttempt.class, EntityManagerWrapper.class, StandardMapper.class }) +@ComponentScan(basePackageClasses = { Context.class, JpaAttempt.class, EntityManagerWrapper.class, StrictMapper.class }) @DirtiesContext class ContextIntegrationTests { diff --git a/src/test/java/net/hostsharing/hsadminng/rbac/role/RbacRoleControllerRestTest.java b/src/test/java/net/hostsharing/hsadminng/rbac/role/RbacRoleControllerRestTest.java index d79a5578..3c4360d6 100644 --- a/src/test/java/net/hostsharing/hsadminng/rbac/role/RbacRoleControllerRestTest.java +++ b/src/test/java/net/hostsharing/hsadminng/rbac/role/RbacRoleControllerRestTest.java @@ -1,7 +1,7 @@ package net.hostsharing.hsadminng.rbac.role; import net.hostsharing.hsadminng.context.Context; -import net.hostsharing.hsadminng.mapper.StandardMapper; +import net.hostsharing.hsadminng.mapper.StrictMapper; import net.hostsharing.hsadminng.persistence.EntityManagerWrapper; import net.hostsharing.hsadminng.config.DisableSecurityConfig; import org.junit.jupiter.api.BeforeEach; @@ -31,7 +31,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; @WebMvcTest(RbacRoleController.class) -@Import({StandardMapper.class, DisableSecurityConfig.class}) +@Import({StrictMapper.class, DisableSecurityConfig.class}) @ActiveProfiles("test") @RunWith(SpringRunner.class) class RbacRoleControllerRestTest { diff --git a/src/test/java/net/hostsharing/hsadminng/rbac/subject/RbacSubjectControllerRestTest.java b/src/test/java/net/hostsharing/hsadminng/rbac/subject/RbacSubjectControllerRestTest.java index 917cd7ff..c0fe7847 100644 --- a/src/test/java/net/hostsharing/hsadminng/rbac/subject/RbacSubjectControllerRestTest.java +++ b/src/test/java/net/hostsharing/hsadminng/rbac/subject/RbacSubjectControllerRestTest.java @@ -1,7 +1,7 @@ package net.hostsharing.hsadminng.rbac.subject; import net.hostsharing.hsadminng.context.Context; -import net.hostsharing.hsadminng.mapper.StandardMapper; +import net.hostsharing.hsadminng.mapper.StrictMapper; import net.hostsharing.hsadminng.persistence.EntityManagerWrapper; import net.hostsharing.hsadminng.config.DisableSecurityConfig; import org.junit.jupiter.api.Test; @@ -26,7 +26,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; @WebMvcTest(RbacSubjectController.class) -@Import({StandardMapper.class, DisableSecurityConfig.class}) +@Import({StrictMapper.class, DisableSecurityConfig.class}) @ActiveProfiles("test") @RunWith(SpringRunner.class) class RbacSubjectControllerRestTest { diff --git a/src/test/java/net/hostsharing/hsadminng/rbac/test/MapperUnitTest.java b/src/test/java/net/hostsharing/hsadminng/rbac/test/MapperUnitTest.java index 5d64903f..8c93b0fb 100644 --- a/src/test/java/net/hostsharing/hsadminng/rbac/test/MapperUnitTest.java +++ b/src/test/java/net/hostsharing/hsadminng/rbac/test/MapperUnitTest.java @@ -2,7 +2,7 @@ package net.hostsharing.hsadminng.rbac.test; import lombok.*; import net.hostsharing.hsadminng.errors.DisplayAs; -import net.hostsharing.hsadminng.mapper.StandardMapper; +import net.hostsharing.hsadminng.mapper.StrictMapper; import net.hostsharing.hsadminng.persistence.EntityManagerWrapper; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -27,7 +27,7 @@ class MapperUnitTest { EntityManagerWrapper em; @InjectMocks - StandardMapper mapper; + StrictMapper mapper; final UUID GIVEN_UUID = UUID.randomUUID(); -- 2.39.5 From abd6a48b5e07237fe97f444c902790edf413e867 Mon Sep 17 00:00:00 2001 From: Michael Hoennig Date: Sun, 12 Jan 2025 20:12:44 +0100 Subject: [PATCH 04/35] fix all remaining tests except the RBAC problem --- .../hs/hosting/asset/HsHostingAsset.java | 2 +- .../debitor/HsOfficeDebitorController.java | 19 ++++++++++++++++++- ...HsBookingItemControllerAcceptanceTest.java | 1 - ...ookingProjectControllerAcceptanceTest.java | 1 - 4 files changed, 19 insertions(+), 4 deletions(-) diff --git a/src/main/java/net/hostsharing/hsadminng/hs/hosting/asset/HsHostingAsset.java b/src/main/java/net/hostsharing/hsadminng/hs/hosting/asset/HsHostingAsset.java index d327f354..f8a1d0c3 100644 --- a/src/main/java/net/hostsharing/hsadminng/hs/hosting/asset/HsHostingAsset.java +++ b/src/main/java/net/hostsharing/hsadminng/hs/hosting/asset/HsHostingAsset.java @@ -89,7 +89,7 @@ public abstract class HsHostingAsset implements Stringifyable, BaseEntity subHostingAssets; 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 089d85b2..adcf4235 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 @@ -3,10 +3,12 @@ package net.hostsharing.hsadminng.hs.office.debitor; import io.micrometer.core.annotation.Timed; import net.hostsharing.hsadminng.context.Context; import net.hostsharing.hsadminng.hs.office.bankaccount.HsOfficeBankAccountRepository; +import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactRealRepository; import net.hostsharing.hsadminng.hs.office.generated.api.v1.api.HsOfficeDebitorsApi; import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeDebitorInsertResource; import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeDebitorPatchResource; import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeDebitorResource; +import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonRealRepository; import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationRealEntity; import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationRealRepository; import net.hostsharing.hsadminng.mapper.StrictMapper; @@ -45,6 +47,12 @@ public class HsOfficeDebitorController implements HsOfficeDebitorsApi { @Autowired private HsOfficeRelationRealRepository realRelRepo; + @Autowired + private HsOfficePersonRealRepository realPersonRepo; + + @Autowired + private HsOfficeContactRealRepository realContactRepo; + @Autowired private HsOfficeBankAccountRepository bankAccountRepo; @@ -94,7 +102,7 @@ public class HsOfficeDebitorController implements HsOfficeDebitorsApi { final var entityToSave = mapper.map(body, HsOfficeDebitorEntity.class, RESOURCE_TO_ENTITY_POSTMAPPER); if (body.getDebitorRel() != null) { // FIXME: move this into RESOURCE_TO_ENTITY_POSTMAPPER - final var debitorRel = mapper.map("debitorRel.", body.getDebitorRel(), HsOfficeRelationRealEntity.class); + final var debitorRel = entityToSave.getDebitorRel(); debitorRel.setType(DEBITOR); entityValidator.validateEntityExists("debitorRel.anchorUuid", debitorRel.getAnchor()); entityValidator.validateEntityExists("debitorRel.holderUuid", debitorRel.getHolder()); @@ -196,6 +204,15 @@ public class HsOfficeDebitorController implements HsOfficeDebitorsApi { } final BiConsumer RESOURCE_TO_ENTITY_POSTMAPPER = (resource, entity) -> { + if (resource.getDebitorRel() != null) { + final var debitorRel = realRelRepo.save(HsOfficeRelationRealEntity.builder() + .type(DEBITOR) + .anchor(realPersonRepo.findByUuid(resource.getDebitorRel().getAnchorUuid()).orElseThrow() ) // FIXME + .holder(realPersonRepo.findByUuid(resource.getDebitorRel().getHolderUuid()).orElseThrow() ) // FIXME + .contact(realContactRepo.findByUuid(resource.getDebitorRel().getContactUuid()).orElseThrow() ) // FIXME + .build()); + entity.setDebitorRel(debitorRel); + } if (resource.getRefundBankAccountUuid() != null) { final var bankAccountEntity = bankAccountRepo.findByUuid(resource.getRefundBankAccountUuid()) .orElseThrow(() -> new ValidationException()); // FIXME diff --git a/src/test/java/net/hostsharing/hsadminng/hs/booking/item/HsBookingItemControllerAcceptanceTest.java b/src/test/java/net/hostsharing/hsadminng/hs/booking/item/HsBookingItemControllerAcceptanceTest.java index 4715ad72..ab3b3d08 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/booking/item/HsBookingItemControllerAcceptanceTest.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/booking/item/HsBookingItemControllerAcceptanceTest.java @@ -643,7 +643,6 @@ class HsBookingItemControllerAcceptanceTest extends ContextBasedTestWithCleanup final var givenProject = realProjectRepo.findByCaption(projectCaption).stream() .findAny().orElseThrow(); final var newBookingItem = HsBookingItemRealEntity.builder() - .uuid(UUID.randomUUID()) .project(givenProject) .type(hsBookingItemType) .caption("some test-booking") diff --git a/src/test/java/net/hostsharing/hsadminng/hs/booking/project/HsBookingProjectControllerAcceptanceTest.java b/src/test/java/net/hostsharing/hsadminng/hs/booking/project/HsBookingProjectControllerAcceptanceTest.java index 05313c56..37b54e7e 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/booking/project/HsBookingProjectControllerAcceptanceTest.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/booking/project/HsBookingProjectControllerAcceptanceTest.java @@ -270,7 +270,6 @@ class HsBookingProjectControllerAcceptanceTest extends ContextBasedTestWithClean context.define("superuser-alex@hostsharing.net"); final var givenDebitor = debitorRepo.findByDebitorNumber(debitorNumber).stream().findAny().orElseThrow(); final var newBookingProject = HsBookingProjectRealEntity.builder() - .uuid(UUID.randomUUID()) .debitor(givenDebitor) .caption(caption) .build(); -- 2.39.5 From 4d5cb239f3f29cd0e3cf797bee6acc3d6c5c962b Mon Sep 17 00:00:00 2001 From: Michael Hoennig Date: Mon, 13 Jan 2025 11:13:49 +0100 Subject: [PATCH 05/35] fix StrictMapper related issues and introduce UuidResolver.resolve --- .../debitor/HsOfficeDebitorController.java | 35 +++++++++++-------- .../partner/HsOfficePartnerController.java | 17 ++++++--- .../hsadminng/hs/validation/UuidResolver.java | 17 +++++++++ ...OfficeDebitorControllerAcceptanceTest.java | 2 +- .../HsOfficeMembershipControllerRestTest.java | 6 +++- 5 files changed, 56 insertions(+), 21 deletions(-) create mode 100644 src/main/java/net/hostsharing/hsadminng/hs/validation/UuidResolver.java 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 adcf4235..a3591237 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 @@ -29,6 +29,7 @@ import java.util.UUID; import java.util.function.BiConsumer; import static net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationType.DEBITOR; +import static net.hostsharing.hsadminng.hs.validation.UuidResolver.resolve; import static net.hostsharing.hsadminng.repr.TaggedNumber.cropTag; @RestController @@ -75,9 +76,9 @@ public class HsOfficeDebitorController implements HsOfficeDebitorsApi { final var entities = partnerNumber != null ? debitorRepo.findDebitorsByPartnerNumber(cropTag("P-", partnerNumber)) - : partnerUuid != null - ? debitorRepo.findDebitorsByPartnerUuid(partnerUuid) - : debitorRepo.findDebitorsByOptionalNameLike(name); + : partnerUuid != null + ? debitorRepo.findDebitorsByPartnerUuid(partnerUuid) + : debitorRepo.findDebitorsByOptionalNameLike(name); final var resources = mapper.mapList(entities, HsOfficeDebitorResource.class, ENTITY_TO_RESOURCE_POSTMAPPER); return ResponseEntity.ok(resources); @@ -93,11 +94,14 @@ public class HsOfficeDebitorController implements HsOfficeDebitorsApi { context.define(currentSubject, assumedRoles); - Validate.isTrue(body.getDebitorRel() == null || body.getDebitorRelUuid() == null, + Validate.isTrue( + body.getDebitorRel() == null || body.getDebitorRelUuid() == null, "ERROR: [400] exactly one of debitorRel and debitorRelUuid must be supplied, but found both"); - Validate.isTrue(body.getDebitorRel() != null || body.getDebitorRelUuid() != null, + Validate.isTrue( + body.getDebitorRel() != null || body.getDebitorRelUuid() != null, "ERROR: [400] exactly one of debitorRel and debitorRelUuid must be supplied, but found none"); - Validate.isTrue(body.getDebitorRel() == null || body.getDebitorRel().getMark() == null, + Validate.isTrue( + body.getDebitorRel() == null || body.getDebitorRel().getMark() == null, "ERROR: [400] debitorRel.mark must be null"); final var entityToSave = mapper.map(body, HsOfficeDebitorEntity.class, RESOURCE_TO_ENTITY_POSTMAPPER); @@ -206,21 +210,24 @@ public class HsOfficeDebitorController implements HsOfficeDebitorsApi { final BiConsumer RESOURCE_TO_ENTITY_POSTMAPPER = (resource, entity) -> { if (resource.getDebitorRel() != null) { final var debitorRel = realRelRepo.save(HsOfficeRelationRealEntity.builder() - .type(DEBITOR) - .anchor(realPersonRepo.findByUuid(resource.getDebitorRel().getAnchorUuid()).orElseThrow() ) // FIXME - .holder(realPersonRepo.findByUuid(resource.getDebitorRel().getHolderUuid()).orElseThrow() ) // FIXME - .contact(realContactRepo.findByUuid(resource.getDebitorRel().getContactUuid()).orElseThrow() ) // FIXME - .build()); + .type(DEBITOR) + .anchor(resolve( + "debitorRel.anchor.uuid", resource.getDebitorRel().getAnchorUuid(), realPersonRepo::findByUuid)) + .holder(resolve( + "debitorRel.holder.uuid", resource.getDebitorRel().getHolderUuid(), realPersonRepo::findByUuid)) + .contact(resolve( + "debitorRel.contact.uuid", resource.getDebitorRel().getContactUuid(), realContactRepo::findByUuid)) + .build()); entity.setDebitorRel(debitorRel); } if (resource.getRefundBankAccountUuid() != null) { - final var bankAccountEntity = bankAccountRepo.findByUuid(resource.getRefundBankAccountUuid()) - .orElseThrow(() -> new ValidationException()); // FIXME - entity.setRefundBankAccount(bankAccountEntity); + entity.setRefundBankAccount(resolve( + "refundBankAccount.uuid", resource.getRefundBankAccountUuid(), bankAccountRepo::findByUuid)); } }; final BiConsumer ENTITY_TO_RESOURCE_POSTMAPPER = (entity, resource) -> { resource.setDebitorNumber(entity.getTaggedDebitorNumber()); + resource.getPartner().setPartnerNumber(entity.getPartner().getTaggedPartnerNumber()); }; } 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 95871984..8fc54ccf 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 @@ -26,6 +26,7 @@ import jakarta.persistence.EntityManager; import jakarta.persistence.PersistenceContext; import java.util.List; import java.util.UUID; +import java.util.function.BiConsumer; import static net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationType.EX_PARTNER; import static net.hostsharing.hsadminng.repr.TaggedNumber.cropTag; @@ -60,7 +61,7 @@ public class HsOfficePartnerController implements HsOfficePartnersApi { final var entities = partnerRepo.findPartnerByOptionalNameLike(name); - final var resources = mapper.mapList(entities, HsOfficePartnerResource.class); + final var resources = mapper.mapList(entities, HsOfficePartnerResource.class, ENTITY_TO_RESOURCE_POSTMAPPER); return ResponseEntity.ok(resources); } @@ -83,7 +84,7 @@ public class HsOfficePartnerController implements HsOfficePartnersApi { .path("/api/hs/office/partners/{id}") .buildAndExpand(saved.getUuid()) .toUri(); - final var mapped = mapper.map(saved, HsOfficePartnerResource.class); + final var mapped = mapper.map(saved, HsOfficePartnerResource.class, ENTITY_TO_RESOURCE_POSTMAPPER); return ResponseEntity.created(uri).body(mapped); } @@ -101,7 +102,8 @@ public class HsOfficePartnerController implements HsOfficePartnersApi { if (result.isEmpty()) { return ResponseEntity.notFound().build(); } - return ResponseEntity.ok(mapper.map(result.get(), HsOfficePartnerResource.class)); + final var mapped = mapper.map(result.get(), HsOfficePartnerResource.class, ENTITY_TO_RESOURCE_POSTMAPPER); + return ResponseEntity.ok(mapped); } @Override @@ -118,7 +120,8 @@ public class HsOfficePartnerController implements HsOfficePartnersApi { if (result.isEmpty()) { return ResponseEntity.notFound().build(); } - return ResponseEntity.ok(mapper.map(result.get(), HsOfficePartnerResource.class)); + final var mapped = mapper.map(result.get(), HsOfficePartnerResource.class, ENTITY_TO_RESOURCE_POSTMAPPER); + return ResponseEntity.ok(mapped); } @Override @@ -161,7 +164,7 @@ public class HsOfficePartnerController implements HsOfficePartnersApi { final var saved = partnerRepo.save(current); optionallyCreateExPartnerRelation(saved, previousPartnerRel); - final var mapped = mapper.map(saved, HsOfficePartnerResource.class); + final var mapped = mapper.map(saved, HsOfficePartnerResource.class, ENTITY_TO_RESOURCE_POSTMAPPER); return ResponseEntity.ok(mapped); } @@ -197,4 +200,8 @@ public class HsOfficePartnerController implements HsOfficePartnersApi { throw new ReferenceNotFoundException(entityClass, uuid, exc); } } + + final BiConsumer ENTITY_TO_RESOURCE_POSTMAPPER = (entity, resource) -> { + resource.setPartnerNumber(entity.getTaggedPartnerNumber()); + }; } diff --git a/src/main/java/net/hostsharing/hsadminng/hs/validation/UuidResolver.java b/src/main/java/net/hostsharing/hsadminng/hs/validation/UuidResolver.java new file mode 100644 index 00000000..6ff98ca1 --- /dev/null +++ b/src/main/java/net/hostsharing/hsadminng/hs/validation/UuidResolver.java @@ -0,0 +1,17 @@ +package net.hostsharing.hsadminng.hs.validation; + +import lombok.experimental.UtilityClass; + +import jakarta.validation.ValidationException; +import java.util.Optional; +import java.util.UUID; +import java.util.function.Function; + +@UtilityClass +public class UuidResolver { + + public static T resolve(final String jsonPath, final UUID uuid, final Function> findByUuid) { + return findByUuid.apply(uuid) + .orElseThrow(() -> new ValidationException("Unable to find " + jsonPath + ": " + uuid)); + } +} 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 7d72d56b..c2009ce4 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 @@ -467,7 +467,7 @@ class HsOfficeDebitorControllerAcceptanceTest extends ContextBasedTestWithCleanu .post("http://localhost/api/hs/office/debitors") .then().log().all().assertThat() .statusCode(400) - .body("message", is("ERROR: [400] Unable to find RealContact by debitorRel.contactUuid: 00000000-0000-0000-0000-000000000000")); + .body("message", is("ERROR: [400] Unable to find debitorRel.contact.uuid: 00000000-0000-0000-0000-000000000000")); // @formatter:on } 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 5cbb4f5f..f5ee81f3 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 @@ -3,6 +3,7 @@ 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.partner.HsOfficePartnerEntity; +import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerRepository; import net.hostsharing.hsadminng.mapper.StrictMapper; import net.hostsharing.hsadminng.persistence.EntityManagerWrapper; import net.hostsharing.hsadminng.config.DisableSecurityConfig; @@ -75,6 +76,9 @@ public class HsOfficeMembershipControllerRestTest { @MockBean HsOfficeCoopAssetsTransactionRepository coopAssetsTransactionRepo; + @MockBean + HsOfficePartnerRepository partnerRepo; + @MockBean HsOfficeMembershipRepository membershipRepo; @@ -275,7 +279,7 @@ public class HsOfficeMembershipControllerRestTest { .andExpect(jsonPath("statusPhrase", is("Bad Request"))) .andExpect(jsonPath( "message", - is("ERROR: [400] Unable to find Partner by partner.uuid: " + givenPartnerUuid))); + is("ERROR: [400] partnerUuid " + givenPartnerUuid + " not found"))); } @ParameterizedTest -- 2.39.5 From e879a61dc7e1616cffe4ed02943a6e2e4e912ee3 Mon Sep 17 00:00:00 2001 From: Michael Hoennig Date: Mon, 13 Jan 2025 11:18:23 +0100 Subject: [PATCH 06/35] deprecated @MockBean -> @MockitoBean --- .../item/HsBookingItemControllerRestTest.java | 12 ++++++------ .../HsBookingItemRepositoryIntegrationTest.java | 4 ++-- .../HsBookingProjectRepositoryIntegrationTest.java | 4 ++-- .../asset/HsHostingAssetControllerRestTest.java | 14 +++++++------- .../HsHostingAssetRepositoryIntegrationTest.java | 4 ++-- .../hsadminng/hs/migration/CsvDataImport.java | 4 ++-- .../HsOfficeBankAccountControllerRestTest.java | 8 ++++---- ...OfficeBankAccountRepositoryIntegrationTest.java | 4 ++-- ...OfficeContactRbacRepositoryIntegrationTest.java | 4 ++-- ...iceCoopAssetsTransactionControllerRestTest.java | 10 +++++----- ...AssetsTransactionRepositoryIntegrationTest.java | 4 ++-- ...iceCoopSharesTransactionControllerRestTest.java | 8 ++++---- ...SharesTransactionRepositoryIntegrationTest.java | 4 ++-- .../HsOfficeDebitorRepositoryIntegrationTest.java | 4 ++-- .../HsOfficeMembershipControllerRestTest.java | 12 ++++++------ ...sOfficeMembershipRepositoryIntegrationTest.java | 4 ++-- .../partner/HsOfficePartnerControllerRestTest.java | 12 ++++++------ .../HsOfficePartnerRepositoryIntegrationTest.java | 4 ++-- ...sOfficePersonRbacRepositoryIntegrationTest.java | 4 ++-- ...sOfficePersonRealRepositoryIntegrationTest.java | 4 ++-- ...fficeRealRelationRepositoryIntegrationTest.java | 4 ++-- .../HsOfficeRelationRepositoryIntegrationTest.java | 4 ++-- ...OfficeSepaMandateRepositoryIntegrationTest.java | 4 ++-- .../rbac/context/ContextIntegrationTests.java | 4 ++-- .../grant/RbacGrantRepositoryIntegrationTest.java | 4 ++-- .../RbacGrantsDiagramServiceIntegrationTest.java | 4 ++-- .../rbac/role/RbacRoleControllerRestTest.java | 10 +++++----- .../role/RbacRoleRepositoryIntegrationTest.java | 4 ++-- .../subject/RbacSubjectControllerRestTest.java | 8 ++++---- .../RbacSubjectRepositoryIntegrationTest.java | 4 ++-- .../TestCustomerRepositoryIntegrationTest.java | 4 ++-- .../pac/TestPackageRepositoryIntegrationTest.java | 4 ++-- 32 files changed, 93 insertions(+), 93 deletions(-) diff --git a/src/test/java/net/hostsharing/hsadminng/hs/booking/item/HsBookingItemControllerRestTest.java b/src/test/java/net/hostsharing/hsadminng/hs/booking/item/HsBookingItemControllerRestTest.java index 7c0c68b0..0d7b11f7 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/booking/item/HsBookingItemControllerRestTest.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/booking/item/HsBookingItemControllerRestTest.java @@ -14,7 +14,7 @@ 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.context.TestConfiguration; -import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.test.context.bean.override.mockito.MockitoBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Import; import org.springframework.http.MediaType; @@ -48,23 +48,23 @@ class HsBookingItemControllerRestTest { @Autowired MockMvc mockMvc; - @MockBean + @MockitoBean Context contextMock; @Autowired @SuppressWarnings("unused") // not used in test, but in controller class StrictMapper mapper; - @MockBean + @MockitoBean EntityManagerWrapper em; - @MockBean + @MockitoBean EntityManagerFactory emf; - @MockBean + @MockitoBean HsBookingProjectRealRepository realProjectRepo; - @MockBean + @MockitoBean HsBookingItemRbacRepository rbacBookingItemRepo; @TestConfiguration diff --git a/src/test/java/net/hostsharing/hsadminng/hs/booking/item/HsBookingItemRepositoryIntegrationTest.java b/src/test/java/net/hostsharing/hsadminng/hs/booking/item/HsBookingItemRepositoryIntegrationTest.java index b6c8d757..9a222b0c 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/booking/item/HsBookingItemRepositoryIntegrationTest.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/booking/item/HsBookingItemRepositoryIntegrationTest.java @@ -13,7 +13,7 @@ import org.junit.jupiter.api.Nested; 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.test.context.bean.override.mockito.MockitoBean; import org.springframework.context.annotation.Import; import org.springframework.orm.jpa.JpaSystemException; @@ -61,7 +61,7 @@ class HsBookingItemRepositoryIntegrationTest extends ContextBasedTestWithCleanup @PersistenceContext EntityManager em; - @MockBean + @MockitoBean HttpServletRequest request; @Test diff --git a/src/test/java/net/hostsharing/hsadminng/hs/booking/project/HsBookingProjectRepositoryIntegrationTest.java b/src/test/java/net/hostsharing/hsadminng/hs/booking/project/HsBookingProjectRepositoryIntegrationTest.java index 411d4360..971b1ba8 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/booking/project/HsBookingProjectRepositoryIntegrationTest.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/booking/project/HsBookingProjectRepositoryIntegrationTest.java @@ -13,7 +13,7 @@ import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.EnumSource; 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.test.context.bean.override.mockito.MockitoBean; import org.springframework.context.annotation.Import; import org.springframework.orm.jpa.JpaSystemException; @@ -56,7 +56,7 @@ class HsBookingProjectRepositoryIntegrationTest extends ContextBasedTestWithClea @PersistenceContext EntityManager em; - @MockBean + @MockitoBean HttpServletRequest request; @Test diff --git a/src/test/java/net/hostsharing/hsadminng/hs/hosting/asset/HsHostingAssetControllerRestTest.java b/src/test/java/net/hostsharing/hsadminng/hs/hosting/asset/HsHostingAssetControllerRestTest.java index 6d5f149e..3b10e26e 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/hosting/asset/HsHostingAssetControllerRestTest.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/hosting/asset/HsHostingAssetControllerRestTest.java @@ -24,7 +24,7 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Import; import org.springframework.http.MediaType; import org.springframework.test.context.ActiveProfiles; -import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.test.context.bean.override.mockito.MockitoBean; import org.springframework.test.context.junit4.SpringRunner; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; @@ -62,27 +62,27 @@ public class HsHostingAssetControllerRestTest { @Autowired MockMvc mockMvc; - @MockBean + @MockitoBean Context contextMock; @Autowired @SuppressWarnings("unused") // not used in test, but in controller class StrictMapper mapper; - @MockBean + @MockitoBean EntityManagerWrapper em; - @MockBean + @MockitoBean EntityManagerFactory emf; - @MockBean + @MockitoBean @SuppressWarnings("unused") // bean needs to be present for HsHostingAssetController private HsBookingItemRealRepository realBookingItemRepo; - @MockBean + @MockitoBean private HsHostingAssetRealRepository realAssetRepo; - @MockBean + @MockitoBean private HsHostingAssetRbacRepository rbacAssetRepo; @TestConfiguration diff --git a/src/test/java/net/hostsharing/hsadminng/hs/hosting/asset/HsHostingAssetRepositoryIntegrationTest.java b/src/test/java/net/hostsharing/hsadminng/hs/hosting/asset/HsHostingAssetRepositoryIntegrationTest.java index 90ac5bf6..4024d16f 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/hosting/asset/HsHostingAssetRepositoryIntegrationTest.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/hosting/asset/HsHostingAssetRepositoryIntegrationTest.java @@ -17,7 +17,7 @@ import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.EnumSource; 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.test.context.bean.override.mockito.MockitoBean; import org.springframework.context.annotation.Import; import org.springframework.orm.jpa.JpaSystemException; @@ -70,7 +70,7 @@ class HsHostingAssetRepositoryIntegrationTest extends ContextBasedTestWithCleanu @PersistenceContext EntityManager em; - @MockBean + @MockitoBean HttpServletRequest request; @Test diff --git a/src/test/java/net/hostsharing/hsadminng/hs/migration/CsvDataImport.java b/src/test/java/net/hostsharing/hsadminng/hs/migration/CsvDataImport.java index 049681e4..811f3752 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/migration/CsvDataImport.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/migration/CsvDataImport.java @@ -14,7 +14,7 @@ import org.junit.jupiter.api.extension.TestWatcher; import org.opentest4j.AssertionFailedError; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; -import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.test.context.bean.override.mockito.MockitoBean; import org.springframework.core.io.Resource; import org.springframework.transaction.support.TransactionTemplate; @@ -76,7 +76,7 @@ public class CsvDataImport extends ContextBasedTest { @Autowired JpaAttempt jpaAttempt; - @MockBean + @MockitoBean HttpServletRequest request; static final LinkedHashSet errors = new LinkedHashSet<>(); diff --git a/src/test/java/net/hostsharing/hsadminng/hs/office/bankaccount/HsOfficeBankAccountControllerRestTest.java b/src/test/java/net/hostsharing/hsadminng/hs/office/bankaccount/HsOfficeBankAccountControllerRestTest.java index 06010ce1..597421a3 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/office/bankaccount/HsOfficeBankAccountControllerRestTest.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/office/bankaccount/HsOfficeBankAccountControllerRestTest.java @@ -7,7 +7,7 @@ import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.EnumSource; 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.test.context.bean.override.mockito.MockitoBean; import org.springframework.context.annotation.Import; import org.springframework.http.MediaType; import org.springframework.test.context.ActiveProfiles; @@ -26,14 +26,14 @@ class HsOfficeBankAccountControllerRestTest { @Autowired MockMvc mockMvc; - @MockBean + @MockitoBean Context contextMock; - @MockBean + @MockitoBean @SuppressWarnings("unused") // not used in test, but in controller class StrictMapper mapper; - @MockBean + @MockitoBean HsOfficeBankAccountRepository bankAccountRepo; enum InvalidIbanTestCase { diff --git a/src/test/java/net/hostsharing/hsadminng/hs/office/bankaccount/HsOfficeBankAccountRepositoryIntegrationTest.java b/src/test/java/net/hostsharing/hsadminng/hs/office/bankaccount/HsOfficeBankAccountRepositoryIntegrationTest.java index f0f197d9..7a95b503 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/office/bankaccount/HsOfficeBankAccountRepositoryIntegrationTest.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/office/bankaccount/HsOfficeBankAccountRepositoryIntegrationTest.java @@ -11,7 +11,7 @@ import org.junit.jupiter.api.Nested; 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.test.context.bean.override.mockito.MockitoBean; import org.springframework.context.annotation.Import; import jakarta.persistence.EntityManager; @@ -46,7 +46,7 @@ class HsOfficeBankAccountRepositoryIntegrationTest extends ContextBasedTestWithC @Autowired JpaAttempt jpaAttempt; - @MockBean + @MockitoBean HttpServletRequest request; @Nested diff --git a/src/test/java/net/hostsharing/hsadminng/hs/office/contact/HsOfficeContactRbacRepositoryIntegrationTest.java b/src/test/java/net/hostsharing/hsadminng/hs/office/contact/HsOfficeContactRbacRepositoryIntegrationTest.java index 5b59f3b6..7e652325 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/office/contact/HsOfficeContactRbacRepositoryIntegrationTest.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/office/contact/HsOfficeContactRbacRepositoryIntegrationTest.java @@ -11,7 +11,7 @@ import org.junit.jupiter.api.Nested; 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.test.context.bean.override.mockito.MockitoBean; import org.springframework.context.annotation.Import; import jakarta.persistence.EntityManager; @@ -46,7 +46,7 @@ class HsOfficeContactRbacRepositoryIntegrationTest extends ContextBasedTestWithC @Autowired JpaAttempt jpaAttempt; - @MockBean + @MockitoBean HttpServletRequest request; @Nested diff --git a/src/test/java/net/hostsharing/hsadminng/hs/office/coopassets/HsOfficeCoopAssetsTransactionControllerRestTest.java b/src/test/java/net/hostsharing/hsadminng/hs/office/coopassets/HsOfficeCoopAssetsTransactionControllerRestTest.java index b9cb7aff..3e657a30 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/office/coopassets/HsOfficeCoopAssetsTransactionControllerRestTest.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/office/coopassets/HsOfficeCoopAssetsTransactionControllerRestTest.java @@ -17,10 +17,10 @@ import org.junit.jupiter.params.provider.EnumSource; 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.context.annotation.Import; import org.springframework.http.MediaType; import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.bean.override.mockito.MockitoBean; import org.springframework.test.context.junit4.SpringRunner; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; @@ -499,20 +499,20 @@ class HsOfficeCoopAssetsTransactionControllerRestTest { @Autowired MockMvc mockMvc; - @MockBean + @MockitoBean Context contextMock; @Autowired @SuppressWarnings("unused") // not used in test, but in controller class StrictMapper mapper; - @MockBean + @MockitoBean EntityManagerWrapper emw; // even if not used in test anymore, it's needed by base-class of StrictMapper - @MockBean + @MockitoBean HsOfficeCoopAssetsTransactionRepository coopAssetsTransactionRepo; - @MockBean + @MockitoBean HsOfficeMembershipRepository membershipRepo; static final String INSERT_REQUEST_BODY_TEMPLATE = """ 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 01248496..706c8034 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 @@ -13,7 +13,7 @@ import org.junit.jupiter.api.Nested; 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.test.context.bean.override.mockito.MockitoBean; import org.springframework.context.annotation.Import; import jakarta.persistence.EntityManager; @@ -51,7 +51,7 @@ class HsOfficeCoopAssetsTransactionRepositoryIntegrationTest extends ContextBase @Autowired JpaAttempt jpaAttempt; - @MockBean + @MockitoBean HttpServletRequest request; @Nested diff --git a/src/test/java/net/hostsharing/hsadminng/hs/office/coopshares/HsOfficeCoopSharesTransactionControllerRestTest.java b/src/test/java/net/hostsharing/hsadminng/hs/office/coopshares/HsOfficeCoopSharesTransactionControllerRestTest.java index f6ed87ed..c207960f 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/office/coopshares/HsOfficeCoopSharesTransactionControllerRestTest.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/office/coopshares/HsOfficeCoopSharesTransactionControllerRestTest.java @@ -8,7 +8,7 @@ import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.EnumSource; 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.test.context.bean.override.mockito.MockitoBean; import org.springframework.context.annotation.Import; import org.springframework.http.MediaType; import org.springframework.test.context.ActiveProfiles; @@ -31,14 +31,14 @@ class HsOfficeCoopSharesTransactionControllerRestTest { @Autowired MockMvc mockMvc; - @MockBean + @MockitoBean Context contextMock; - @MockBean + @MockitoBean @SuppressWarnings("unused") // not used in test, but in controller class StrictMapper mapper; - @MockBean + @MockitoBean HsOfficeCoopSharesTransactionRepository coopSharesTransactionRepo; static final String VALID_INSERT_REQUEST_BODY = """ 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 d428a9d7..afeae8c3 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 @@ -13,7 +13,7 @@ import org.junit.jupiter.api.Nested; 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.test.context.bean.override.mockito.MockitoBean; import org.springframework.context.annotation.Import; import jakarta.persistence.EntityManager; @@ -50,7 +50,7 @@ class HsOfficeCoopSharesTransactionRepositoryIntegrationTest extends ContextBase @Autowired JpaAttempt jpaAttempt; - @MockBean + @MockitoBean HttpServletRequest request; @Nested 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 948ec958..c461a8ba 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 @@ -22,7 +22,7 @@ import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.ValueSource; 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.test.context.bean.override.mockito.MockitoBean; import org.springframework.context.annotation.Import; import org.springframework.orm.jpa.JpaSystemException; import org.springframework.transaction.annotation.Transactional; @@ -74,7 +74,7 @@ class HsOfficeDebitorRepositoryIntegrationTest extends ContextBasedTestWithClean @Autowired RbacGrantsDiagramService mermaidService; - @MockBean + @MockitoBean HttpServletRequest request; @Nested class CreateDebitor { 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 f5ee81f3..216b0298 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 @@ -13,7 +13,7 @@ import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.EnumSource; 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.test.context.bean.override.mockito.MockitoBean; import org.springframework.context.annotation.Import; import org.springframework.http.MediaType; import org.springframework.test.context.ActiveProfiles; @@ -70,19 +70,19 @@ public class HsOfficeMembershipControllerRestTest { @Autowired MockMvc mockMvc; - @MockBean + @MockitoBean Context contextMock; - @MockBean + @MockitoBean HsOfficeCoopAssetsTransactionRepository coopAssetsTransactionRepo; - @MockBean + @MockitoBean HsOfficePartnerRepository partnerRepo; - @MockBean + @MockitoBean HsOfficeMembershipRepository membershipRepo; - @MockBean + @MockitoBean EntityManagerWrapper em; @Nested 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 fc3599d2..13c5396a 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 @@ -13,7 +13,7 @@ import org.junit.jupiter.api.Nested; 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.test.context.bean.override.mockito.MockitoBean; import org.springframework.context.annotation.Import; import org.springframework.orm.jpa.JpaSystemException; @@ -54,7 +54,7 @@ class HsOfficeMembershipRepositoryIntegrationTest extends ContextBasedTestWithCl @Autowired JpaAttempt jpaAttempt; - @MockBean + @MockitoBean HttpServletRequest request; @Nested diff --git a/src/test/java/net/hostsharing/hsadminng/hs/office/partner/HsOfficePartnerControllerRestTest.java b/src/test/java/net/hostsharing/hsadminng/hs/office/partner/HsOfficePartnerControllerRestTest.java index 44a7c4b3..13a81cdb 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/office/partner/HsOfficePartnerControllerRestTest.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/office/partner/HsOfficePartnerControllerRestTest.java @@ -14,7 +14,7 @@ import org.junit.jupiter.api.Test; import org.mockito.Mock; 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.test.context.bean.override.mockito.MockitoBean; import org.springframework.context.annotation.Import; import org.springframework.http.MediaType; import org.springframework.test.context.ActiveProfiles; @@ -50,19 +50,19 @@ class HsOfficePartnerControllerRestTest { @Autowired MockMvc mockMvc; - @MockBean + @MockitoBean Context contextMock; - @MockBean + @MockitoBean HsOfficePartnerRepository partnerRepo; - @MockBean + @MockitoBean HsOfficeRelationRealRepository relationRepo; - @MockBean + @MockitoBean EntityManagerWrapper em; - @MockBean + @MockitoBean EntityManagerFactory emf; @Mock 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 1ce4df3d..b625bfb9 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 @@ -16,7 +16,7 @@ import org.junit.jupiter.api.Nested; 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; // FIXME: use MockitoBean +import org.springframework.test.context.bean.override.mockito.MockitoBean; // FIXME: use MockitoBean import org.springframework.context.annotation.Import; import org.springframework.orm.jpa.JpaSystemException; @@ -67,7 +67,7 @@ class HsOfficePartnerRepositoryIntegrationTest extends ContextBasedTestWithClean @Autowired JpaAttempt jpaAttempt; - @MockBean + @MockitoBean HttpServletRequest request; @Nested diff --git a/src/test/java/net/hostsharing/hsadminng/hs/office/person/HsOfficePersonRbacRepositoryIntegrationTest.java b/src/test/java/net/hostsharing/hsadminng/hs/office/person/HsOfficePersonRbacRepositoryIntegrationTest.java index 481847c2..aff5561b 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/office/person/HsOfficePersonRbacRepositoryIntegrationTest.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/office/person/HsOfficePersonRbacRepositoryIntegrationTest.java @@ -11,7 +11,7 @@ import org.junit.jupiter.api.Nested; 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.test.context.bean.override.mockito.MockitoBean; import org.springframework.context.annotation.Import; import jakarta.persistence.EntityManager; @@ -46,7 +46,7 @@ class HsOfficePersonRbacRepositoryIntegrationTest extends ContextBasedTestWithCl @Autowired JpaAttempt jpaAttempt; - @MockBean + @MockitoBean HttpServletRequest request; @Nested diff --git a/src/test/java/net/hostsharing/hsadminng/hs/office/person/HsOfficePersonRealRepositoryIntegrationTest.java b/src/test/java/net/hostsharing/hsadminng/hs/office/person/HsOfficePersonRealRepositoryIntegrationTest.java index 2fc268a6..0d89050e 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/office/person/HsOfficePersonRealRepositoryIntegrationTest.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/office/person/HsOfficePersonRealRepositoryIntegrationTest.java @@ -10,7 +10,7 @@ import org.junit.jupiter.api.Nested; 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.test.context.bean.override.mockito.MockitoBean; import org.springframework.context.annotation.Import; import jakarta.persistence.EntityManager; @@ -44,7 +44,7 @@ class HsOfficePersonRealRepositoryIntegrationTest extends ContextBasedTestWithCl @Autowired JpaAttempt jpaAttempt; - @MockBean + @MockitoBean HttpServletRequest request; @Autowired private HsOfficePersonRealRepository hsOfficePersonRealRepository; diff --git a/src/test/java/net/hostsharing/hsadminng/hs/office/relation/HsOfficeRealRelationRepositoryIntegrationTest.java b/src/test/java/net/hostsharing/hsadminng/hs/office/relation/HsOfficeRealRelationRepositoryIntegrationTest.java index 05c2d971..4c8f7b75 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/office/relation/HsOfficeRealRelationRepositoryIntegrationTest.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/office/relation/HsOfficeRealRelationRepositoryIntegrationTest.java @@ -9,7 +9,7 @@ import org.junit.jupiter.api.Nested; 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.test.context.bean.override.mockito.MockitoBean; import org.springframework.context.annotation.Import; import jakarta.persistence.EntityManager; @@ -35,7 +35,7 @@ class HsOfficeRealRelationRepositoryIntegrationTest extends ContextBasedTestWith @PersistenceContext EntityManager em; - @MockBean + @MockitoBean HttpServletRequest request; @Nested diff --git a/src/test/java/net/hostsharing/hsadminng/hs/office/relation/HsOfficeRelationRepositoryIntegrationTest.java b/src/test/java/net/hostsharing/hsadminng/hs/office/relation/HsOfficeRelationRepositoryIntegrationTest.java index eb92aad9..df3bcf23 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/office/relation/HsOfficeRelationRepositoryIntegrationTest.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/office/relation/HsOfficeRelationRepositoryIntegrationTest.java @@ -13,7 +13,7 @@ import org.junit.jupiter.api.Nested; 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.test.context.bean.override.mockito.MockitoBean; import org.springframework.context.annotation.Import; import org.springframework.orm.jpa.JpaSystemException; @@ -58,7 +58,7 @@ class HsOfficeRelationRepositoryIntegrationTest extends ContextBasedTestWithClea @Autowired JpaAttempt jpaAttempt; - @MockBean + @MockitoBean HttpServletRequest request; @Nested 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 8e7512c3..3debf9f5 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 @@ -13,7 +13,7 @@ import org.junit.jupiter.api.Nested; 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.test.context.bean.override.mockito.MockitoBean; import org.springframework.context.annotation.Import; import org.springframework.orm.jpa.JpaSystemException; @@ -55,7 +55,7 @@ class HsOfficeSepaMandateRepositoryIntegrationTest extends ContextBasedTestWithC @PersistenceContext EntityManager em; - @MockBean + @MockitoBean HttpServletRequest request; @Nested diff --git a/src/test/java/net/hostsharing/hsadminng/rbac/context/ContextIntegrationTests.java b/src/test/java/net/hostsharing/hsadminng/rbac/context/ContextIntegrationTests.java index d0f6df12..7f59d4e3 100644 --- a/src/test/java/net/hostsharing/hsadminng/rbac/context/ContextIntegrationTests.java +++ b/src/test/java/net/hostsharing/hsadminng/rbac/context/ContextIntegrationTests.java @@ -8,7 +8,7 @@ import net.hostsharing.hsadminng.rbac.test.JpaAttempt; 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.test.context.bean.override.mockito.MockitoBean; import org.springframework.context.annotation.ComponentScan; import org.springframework.test.annotation.DirtiesContext; import org.springframework.transaction.annotation.Transactional; @@ -27,7 +27,7 @@ class ContextIntegrationTests { @Autowired private Context context; - @MockBean + @MockitoBean @SuppressWarnings("unused") // the bean must be present, even though it's not used directly private HttpServletRequest request; diff --git a/src/test/java/net/hostsharing/hsadminng/rbac/grant/RbacGrantRepositoryIntegrationTest.java b/src/test/java/net/hostsharing/hsadminng/rbac/grant/RbacGrantRepositoryIntegrationTest.java index 14075fe8..41c2e6fc 100644 --- a/src/test/java/net/hostsharing/hsadminng/rbac/grant/RbacGrantRepositoryIntegrationTest.java +++ b/src/test/java/net/hostsharing/hsadminng/rbac/grant/RbacGrantRepositoryIntegrationTest.java @@ -10,7 +10,7 @@ import org.junit.jupiter.api.Nested; 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.test.context.bean.override.mockito.MockitoBean; import org.springframework.context.annotation.Import; import org.springframework.orm.jpa.JpaSystemException; import org.springframework.transaction.annotation.Propagation; @@ -32,7 +32,7 @@ class RbacGrantRepositoryIntegrationTest extends ContextBasedTest { @Autowired Context context; - @MockBean + @MockitoBean HttpServletRequest request; @Autowired diff --git a/src/test/java/net/hostsharing/hsadminng/rbac/grant/RbacGrantsDiagramServiceIntegrationTest.java b/src/test/java/net/hostsharing/hsadminng/rbac/grant/RbacGrantsDiagramServiceIntegrationTest.java index b234e07b..085854f1 100644 --- a/src/test/java/net/hostsharing/hsadminng/rbac/grant/RbacGrantsDiagramServiceIntegrationTest.java +++ b/src/test/java/net/hostsharing/hsadminng/rbac/grant/RbacGrantsDiagramServiceIntegrationTest.java @@ -10,7 +10,7 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.TestInfo; 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.test.context.bean.override.mockito.MockitoBean; import org.springframework.context.annotation.Import; import jakarta.servlet.http.HttpServletRequest; @@ -28,7 +28,7 @@ class RbacGrantsDiagramServiceIntegrationTest extends ContextBasedTestWithCleanu @Autowired RbacGrantsDiagramService grantsMermaidService; - @MockBean + @MockitoBean HttpServletRequest request; @Autowired diff --git a/src/test/java/net/hostsharing/hsadminng/rbac/role/RbacRoleControllerRestTest.java b/src/test/java/net/hostsharing/hsadminng/rbac/role/RbacRoleControllerRestTest.java index 3c4360d6..a10b1eee 100644 --- a/src/test/java/net/hostsharing/hsadminng/rbac/role/RbacRoleControllerRestTest.java +++ b/src/test/java/net/hostsharing/hsadminng/rbac/role/RbacRoleControllerRestTest.java @@ -9,7 +9,7 @@ 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.test.context.bean.override.mockito.MockitoBean; import org.springframework.context.annotation.Import; import org.springframework.http.MediaType; import org.springframework.test.context.ActiveProfiles; @@ -39,16 +39,16 @@ class RbacRoleControllerRestTest { @Autowired MockMvc mockMvc; - @MockBean + @MockitoBean Context contextMock; - @MockBean + @MockitoBean RbacRoleRepository rbacRoleRepository; - @MockBean + @MockitoBean EntityManagerWrapper em; - @MockBean + @MockitoBean EntityManagerFactory emf; @BeforeEach diff --git a/src/test/java/net/hostsharing/hsadminng/rbac/role/RbacRoleRepositoryIntegrationTest.java b/src/test/java/net/hostsharing/hsadminng/rbac/role/RbacRoleRepositoryIntegrationTest.java index 98495e81..292305e5 100644 --- a/src/test/java/net/hostsharing/hsadminng/rbac/role/RbacRoleRepositoryIntegrationTest.java +++ b/src/test/java/net/hostsharing/hsadminng/rbac/role/RbacRoleRepositoryIntegrationTest.java @@ -7,7 +7,7 @@ import org.junit.jupiter.api.Nested; 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.test.context.bean.override.mockito.MockitoBean; import org.springframework.context.annotation.Import; import org.springframework.orm.jpa.JpaSystemException; @@ -31,7 +31,7 @@ class RbacRoleRepositoryIntegrationTest { @Autowired EntityManager em; - @MockBean + @MockitoBean HttpServletRequest request; @Nested diff --git a/src/test/java/net/hostsharing/hsadminng/rbac/subject/RbacSubjectControllerRestTest.java b/src/test/java/net/hostsharing/hsadminng/rbac/subject/RbacSubjectControllerRestTest.java index c0fe7847..7d929042 100644 --- a/src/test/java/net/hostsharing/hsadminng/rbac/subject/RbacSubjectControllerRestTest.java +++ b/src/test/java/net/hostsharing/hsadminng/rbac/subject/RbacSubjectControllerRestTest.java @@ -8,7 +8,7 @@ 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.test.context.bean.override.mockito.MockitoBean; import org.springframework.context.annotation.Import; import org.springframework.http.MediaType; import org.springframework.test.context.ActiveProfiles; @@ -34,13 +34,13 @@ class RbacSubjectControllerRestTest { @Autowired MockMvc mockMvc; - @MockBean + @MockitoBean Context contextMock; - @MockBean + @MockitoBean RbacSubjectRepository rbacSubjectRepository; - @MockBean + @MockitoBean EntityManagerWrapper em; diff --git a/src/test/java/net/hostsharing/hsadminng/rbac/subject/RbacSubjectRepositoryIntegrationTest.java b/src/test/java/net/hostsharing/hsadminng/rbac/subject/RbacSubjectRepositoryIntegrationTest.java index ea72ce14..00654d6e 100644 --- a/src/test/java/net/hostsharing/hsadminng/rbac/subject/RbacSubjectRepositoryIntegrationTest.java +++ b/src/test/java/net/hostsharing/hsadminng/rbac/subject/RbacSubjectRepositoryIntegrationTest.java @@ -8,7 +8,7 @@ import org.junit.jupiter.api.Nested; 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.test.context.bean.override.mockito.MockitoBean; import org.springframework.context.annotation.Import; import org.springframework.orm.jpa.JpaSystemException; import org.springframework.transaction.annotation.Propagation; @@ -37,7 +37,7 @@ class RbacSubjectRepositoryIntegrationTest extends ContextBasedTest { @PersistenceContext EntityManager em; - @MockBean + @MockitoBean HttpServletRequest request; @Nested diff --git a/src/test/java/net/hostsharing/hsadminng/rbac/test/cust/TestCustomerRepositoryIntegrationTest.java b/src/test/java/net/hostsharing/hsadminng/rbac/test/cust/TestCustomerRepositoryIntegrationTest.java index 245278da..9273179d 100644 --- a/src/test/java/net/hostsharing/hsadminng/rbac/test/cust/TestCustomerRepositoryIntegrationTest.java +++ b/src/test/java/net/hostsharing/hsadminng/rbac/test/cust/TestCustomerRepositoryIntegrationTest.java @@ -7,7 +7,7 @@ import org.junit.jupiter.api.Nested; 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.test.context.bean.override.mockito.MockitoBean; import org.springframework.context.annotation.Import; import jakarta.persistence.PersistenceException; @@ -25,7 +25,7 @@ class TestCustomerRepositoryIntegrationTest extends ContextBasedTest { @Autowired TestCustomerRepository testCustomerRepository; - @MockBean + @MockitoBean HttpServletRequest request; @Nested diff --git a/src/test/java/net/hostsharing/hsadminng/rbac/test/pac/TestPackageRepositoryIntegrationTest.java b/src/test/java/net/hostsharing/hsadminng/rbac/test/pac/TestPackageRepositoryIntegrationTest.java index 5b45f1b5..f4fa58dc 100644 --- a/src/test/java/net/hostsharing/hsadminng/rbac/test/pac/TestPackageRepositoryIntegrationTest.java +++ b/src/test/java/net/hostsharing/hsadminng/rbac/test/pac/TestPackageRepositoryIntegrationTest.java @@ -7,7 +7,7 @@ import org.junit.jupiter.api.Nested; 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.test.context.bean.override.mockito.MockitoBean; import org.springframework.context.annotation.Import; import org.springframework.orm.ObjectOptimisticLockingFailureException; @@ -31,7 +31,7 @@ class TestPackageRepositoryIntegrationTest extends ContextBasedTest { @Autowired JpaAttempt jpaAttempt; - @MockBean + @MockitoBean HttpServletRequest request; @Nested -- 2.39.5 From f49bea556a314c611c825cd71de02603c72c0688 Mon Sep 17 00:00:00 2001 From: Michael Hoennig Date: Mon, 13 Jan 2025 11:29:06 +0100 Subject: [PATCH 07/35] deprecated getAllValidationResults -> getParameterValidationResults --- .../hsadminng/errors/RestResponseEntityExceptionHandler.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/net/hostsharing/hsadminng/errors/RestResponseEntityExceptionHandler.java b/src/main/java/net/hostsharing/hsadminng/errors/RestResponseEntityExceptionHandler.java index 64b72ef8..31ab3647 100644 --- a/src/main/java/net/hostsharing/hsadminng/errors/RestResponseEntityExceptionHandler.java +++ b/src/main/java/net/hostsharing/hsadminng/errors/RestResponseEntityExceptionHandler.java @@ -132,7 +132,7 @@ public class RestResponseEntityExceptionHandler final HttpStatusCode status, final WebRequest request) { final var errorList = exc - .getAllValidationResults() // FIXME: deprecated + .getParameterValidationResults() .stream() .map(ParameterValidationResult::getResolvableErrors) .flatMap(Collection::stream) -- 2.39.5 From 1f05be063b6fa6bb2e8905f0c54c3c2bde8c4336 Mon Sep 17 00:00:00 2001 From: Michael Hoennig Date: Mon, 13 Jan 2025 17:57:32 +0100 Subject: [PATCH 08/35] refactoring, e.g. align CoopAssets+CoopShares and add HsBookingDebitorEntity.WithRoleId --- .../debitor/HsBookingDebitorEntity.java | 3 ++- .../HsOfficeCoopAssetsTransactionEntity.java | 7 +++--- .../debitor/HsOfficeDebitorController.java | 2 +- ...esTransactionControllerAcceptanceTest.java | 24 +++++++++++++++---- ...OfficeDebitorControllerAcceptanceTest.java | 3 ++- 5 files changed, 28 insertions(+), 11 deletions(-) diff --git a/src/main/java/net/hostsharing/hsadminng/hs/booking/debitor/HsBookingDebitorEntity.java b/src/main/java/net/hostsharing/hsadminng/hs/booking/debitor/HsBookingDebitorEntity.java index a09a33bc..f982a443 100644 --- a/src/main/java/net/hostsharing/hsadminng/hs/booking/debitor/HsBookingDebitorEntity.java +++ b/src/main/java/net/hostsharing/hsadminng/hs/booking/debitor/HsBookingDebitorEntity.java @@ -5,6 +5,7 @@ import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; import net.hostsharing.hsadminng.errors.DisplayAs; +import net.hostsharing.hsadminng.rbac.role.WithRoleId; import net.hostsharing.hsadminng.repr.Stringify; import net.hostsharing.hsadminng.repr.Stringifyable; @@ -24,7 +25,7 @@ import static net.hostsharing.hsadminng.repr.Stringify.stringify; @NoArgsConstructor @AllArgsConstructor @DisplayAs("BookingDebitor") -public class HsBookingDebitorEntity implements Stringifyable { +public class HsBookingDebitorEntity implements Stringifyable, WithRoleId { public static final String DEBITOR_NUMBER_TAG = "D-"; 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 c0c908df..4e4b1c41 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 @@ -10,9 +10,9 @@ import net.hostsharing.hsadminng.errors.DisplayAs; import net.hostsharing.hsadminng.hs.office.membership.HsOfficeMembershipEntity; import net.hostsharing.hsadminng.persistence.BaseEntity; import net.hostsharing.hsadminng.rbac.generator.RbacSpec; +import net.hostsharing.hsadminng.rbac.generator.RbacSpec.SQL; import net.hostsharing.hsadminng.repr.Stringify; import net.hostsharing.hsadminng.repr.Stringifyable; -import org.hibernate.annotations.GenericGenerator; import jakarta.persistence.*; import java.io.IOException; @@ -57,8 +57,7 @@ public class HsOfficeCoopAssetsTransactionEntity implements Stringifyable, BaseE .quotedValues(false); @Id - @GeneratedValue(generator = "UUID") - @GenericGenerator(name = "UUID", strategy = "org.hibernate.id.UUIDGenerator") + @GeneratedValue private UUID uuid; @Version @@ -141,7 +140,7 @@ public class HsOfficeCoopAssetsTransactionEntity implements Stringifyable, BaseE public static RbacSpec rbac() { return rbacViewFor("coopAssetsTransaction", HsOfficeCoopAssetsTransactionEntity.class) - .withIdentityView(RbacSpec.SQL.projection("reference")) + .withIdentityView(SQL.projection("reference")) .withUpdatableColumns("comment") .importEntityAlias("membership", HsOfficeMembershipEntity.class, usingDefaultCase(), dependsOnColumn("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 a3591237..73ede563 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 @@ -197,7 +197,7 @@ public class HsOfficeDebitorController implements HsOfficeDebitorsApi { context.define(currentSubject, assumedRoles); - final var current = debitorRepo.findByUuid(debitorUuid).orElseThrow(); + final var current = debitorRepo.findByUuid(debitorUuid).orElseThrow().load(); new HsOfficeDebitorEntityPatcher(em, current).apply(body); diff --git a/src/test/java/net/hostsharing/hsadminng/hs/office/coopshares/HsOfficeCoopSharesTransactionControllerAcceptanceTest.java b/src/test/java/net/hostsharing/hsadminng/hs/office/coopshares/HsOfficeCoopSharesTransactionControllerAcceptanceTest.java index 55411a10..810f0a60 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/office/coopshares/HsOfficeCoopSharesTransactionControllerAcceptanceTest.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/office/coopshares/HsOfficeCoopSharesTransactionControllerAcceptanceTest.java @@ -170,7 +170,9 @@ class HsOfficeCoopSharesTransactionControllerAcceptanceTest extends ContextBased final var givenMembership = membershipRepo.findMembershipByMemberNumber(1000101).orElseThrow(); final var location = RestAssured // @formatter:off - .given().header("current-subject", "superuser-alex@hostsharing.net").contentType(ContentType.JSON).body(""" + .given() + .header("current-subject", "superuser-alex@hostsharing.net") + .contentType(ContentType.JSON).body(""" { "membership.uuid": "%s", "transactionType": "SUBSCRIPTION", @@ -179,15 +181,29 @@ class HsOfficeCoopSharesTransactionControllerAcceptanceTest extends ContextBased "reference": "temp ref A", "comment": "just some test coop shares transaction" } - """.formatted(givenMembership.getUuid())).port(port).when().post("http://localhost/api/hs/office/coopsharestransactions").then().log().all().assertThat().statusCode(201).contentType(ContentType.JSON).body("uuid", isUuidValid()).body("", lenientlyEquals(""" + """.formatted(givenMembership.getUuid())) + .port(port) + .when() + .post("http://localhost/api/hs/office/coopsharestransactions") + .then() + .log().all() + .assertThat() + .statusCode(201) + .contentType(ContentType.JSON) + .body("uuid", isUuidValid()) + .body("", lenientlyEquals(""" { + "membership.uuid": "%s", "transactionType": "SUBSCRIPTION", "shareCount": 8, "valueDate": "2022-10-13", "reference": "temp ref A", "comment": "just some test coop shares transaction" } - """)).header("Location", startsWith("http://localhost")).extract().header("Location"); // @formatter:on + """.formatted(givenMembership.getUuid()))) + .header("Location", startsWith("http://localhost")) + .extract() + .header("Location"); // @formatter:on // finally, the new coopSharesTransaction can be accessed under the generated UUID final var newShareTxUuid = UUID.fromString(location.substring(location.lastIndexOf('/') + 1)); @@ -197,7 +213,7 @@ class HsOfficeCoopSharesTransactionControllerAcceptanceTest extends ContextBased @Test void globalAdmin_canAddCoopSharesReversalTransaction() { - context.define("superuser-alex@hostsharing.net", "global#global:ADMIN"); + context.define("superuser-alex@hostsharing.net", "rbac.global#global:ADMIN"); final var givenMembership = membershipRepo.findMembershipByMemberNumber(1000101).orElseThrow(); final var givenTransaction = jpaAttempt.transacted(() -> { // TODO.impl: introduce something like transactedAsSuperuser / transactedAs("...", ...) 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 c2009ce4..cd0f4105 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 @@ -10,6 +10,7 @@ import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerRepository; import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonRealRepository; import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationRealEntity; import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationRealRepository; +import net.hostsharing.hsadminng.rbac.role.RbacRoleType; import net.hostsharing.hsadminng.rbac.test.ContextBasedTestWithCleanup; import net.hostsharing.hsadminng.rbac.test.JpaAttempt; import net.hostsharing.hsadminng.config.DisableSecurityConfig; @@ -704,7 +705,7 @@ class HsOfficeDebitorControllerAcceptanceTest extends ContextBasedTestWithCleanu RestAssured // @formatter:off .given() .header("current-subject", "superuser-alex@hostsharing.net") - .header("assumed-roles", "hs_office.contact#tenthcontact:ADMIN") + .header("assumed-roles", givenDebitor.getDebitorRel().roleId(RbacRoleType.ADMIN) ) .contentType(ContentType.JSON) .body(""" { -- 2.39.5 From 1a234d1528f09908e038f90193100899b23986f6 Mon Sep 17 00:00:00 2001 From: Michael Hoennig Date: Mon, 13 Jan 2025 18:17:32 +0100 Subject: [PATCH 09/35] fix theContactAdmin_canNotPatchARelatedDebitor --- .../hs/office/contact/HsOfficeContact.java | 3 ++- .../office/debitor/HsOfficeDebitorController.java | 4 +++- .../hs/office/partner/HsOfficePartnerEntity.java | 4 +++- .../HsOfficeDebitorControllerAcceptanceTest.java | 14 +++++++------- 4 files changed, 15 insertions(+), 10 deletions(-) diff --git a/src/main/java/net/hostsharing/hsadminng/hs/office/contact/HsOfficeContact.java b/src/main/java/net/hostsharing/hsadminng/hs/office/contact/HsOfficeContact.java index dc5bca3e..63d6cfd5 100644 --- a/src/main/java/net/hostsharing/hsadminng/hs/office/contact/HsOfficeContact.java +++ b/src/main/java/net/hostsharing/hsadminng/hs/office/contact/HsOfficeContact.java @@ -12,6 +12,7 @@ import lombok.experimental.SuperBuilder; import net.hostsharing.hsadminng.errors.DisplayAs; import net.hostsharing.hsadminng.mapper.PatchableMapWrapper; import net.hostsharing.hsadminng.persistence.BaseEntity; +import net.hostsharing.hsadminng.rbac.role.WithRoleId; import net.hostsharing.hsadminng.repr.Stringify; import net.hostsharing.hsadminng.repr.Stringifyable; import org.hibernate.annotations.GenericGenerator; @@ -37,7 +38,7 @@ import static net.hostsharing.hsadminng.repr.Stringify.stringify; @SuperBuilder(toBuilder = true) @FieldNameConstants @DisplayAs("Contact") -public class HsOfficeContact implements Stringifyable, BaseEntity { +public class HsOfficeContact implements Stringifyable, BaseEntity, WithRoleId { private static Stringify toString = stringify(HsOfficeContact.class, "contact") .withProp(Fields.caption, HsOfficeContact::getCaption) 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 73ede563..70efafd4 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 @@ -228,6 +228,8 @@ public class HsOfficeDebitorController implements HsOfficeDebitorsApi { final BiConsumer ENTITY_TO_RESOURCE_POSTMAPPER = (entity, resource) -> { resource.setDebitorNumber(entity.getTaggedDebitorNumber()); - resource.getPartner().setPartnerNumber(entity.getPartner().getTaggedPartnerNumber()); + if (resource.getPartner() != null) { // FIXME: should not happen + resource.getPartner().setPartnerNumber(entity.getPartner().getTaggedPartnerNumber()); + } }; } 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 69fb49c9..3575b24b 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 @@ -82,7 +82,9 @@ public class HsOfficePartnerEntity implements Stringifyable, BaseEntity Date: Tue, 14 Jan 2025 09:14:22 +0100 Subject: [PATCH 10/35] fix uuid-init in TestCustomerRepositoryIntegrationTest --- .../test/cust/TestCustomerRepositoryIntegrationTest.java | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/test/java/net/hostsharing/hsadminng/rbac/test/cust/TestCustomerRepositoryIntegrationTest.java b/src/test/java/net/hostsharing/hsadminng/rbac/test/cust/TestCustomerRepositoryIntegrationTest.java index 9273179d..c0a0dd06 100644 --- a/src/test/java/net/hostsharing/hsadminng/rbac/test/cust/TestCustomerRepositoryIntegrationTest.java +++ b/src/test/java/net/hostsharing/hsadminng/rbac/test/cust/TestCustomerRepositoryIntegrationTest.java @@ -13,7 +13,6 @@ import org.springframework.context.annotation.Import; import jakarta.persistence.PersistenceException; import jakarta.servlet.http.HttpServletRequest; import java.util.List; -import java.util.UUID; import static net.hostsharing.hsadminng.rbac.test.JpaAttempt.attempt; import static org.assertj.core.api.Assertions.assertThat; @@ -40,7 +39,7 @@ class TestCustomerRepositoryIntegrationTest extends ContextBasedTest { // when final var result = attempt(em, () -> { final var newCustomer = new TestCustomerEntity( - UUID.randomUUID(), 0, "www", 90001, "customer-admin@www.example.com"); + null, 0, "www", 90001, "customer-admin@www.example.com"); return testCustomerRepository.save(newCustomer); }); @@ -59,7 +58,7 @@ class TestCustomerRepositoryIntegrationTest extends ContextBasedTest { // when final var result = attempt(em, () -> { final var newCustomer = new TestCustomerEntity( - UUID.randomUUID(), 0, "www", 90001, "customer-admin@www.example.com"); + null, 0, "www", 90001, "customer-admin@www.example.com"); return testCustomerRepository.save(newCustomer); }); @@ -78,7 +77,7 @@ class TestCustomerRepositoryIntegrationTest extends ContextBasedTest { // when final var result = attempt(em, () -> { final var newCustomer = new TestCustomerEntity( - UUID.randomUUID(), 0, "www", 90001, "customer-admin@www.example.com"); + null, 0, "www", 90001, "customer-admin@www.example.com"); return testCustomerRepository.save(newCustomer); }); -- 2.39.5 From fd874f70c6b0ae6f167773b2a6bd7876585c0a21 Mon Sep 17 00:00:00 2001 From: Michael Hoennig Date: Tue, 14 Jan 2025 11:22:19 +0100 Subject: [PATCH 11/35] align HsOfficeCoopAssetsTransactionEntity and HsOfficeCoopSharesTransactionEntity --- .../HsOfficeCoopAssetsTransactionEntity.java | 22 ++++++++++++++----- .../HsOfficeCoopSharesTransactionEntity.java | 14 ++++++++++-- 2 files changed, 28 insertions(+), 8 deletions(-) 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 4e4b1c41..6dd244aa 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 @@ -1,4 +1,3 @@ - package net.hostsharing.hsadminng.hs.office.coopassets; import lombok.AllArgsConstructor; @@ -14,7 +13,18 @@ import net.hostsharing.hsadminng.rbac.generator.RbacSpec.SQL; import net.hostsharing.hsadminng.repr.Stringify; import net.hostsharing.hsadminng.repr.Stringifyable; -import jakarta.persistence.*; +import jakarta.persistence.CascadeType; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.EnumType; +import jakarta.persistence.Enumerated; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.Id; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.ManyToOne; +import jakarta.persistence.OneToOne; +import jakarta.persistence.Table; +import jakarta.persistence.Version; import java.io.IOException; import java.math.BigDecimal; import java.time.LocalDate; @@ -121,15 +131,15 @@ public class HsOfficeCoopAssetsTransactionEntity implements Stringifyable, BaseE return this; } - public String getTaggedMemberNumber() { - return ofNullable(membership).map(HsOfficeMembershipEntity::toShortString).orElse("M-???????"); - } - @Override public String toString() { return stringify.apply(this); } + public String getTaggedMemberNumber() { + return ofNullable(membership).map(HsOfficeMembershipEntity::toShortString).orElse("M-???????"); + } + @Override public String toShortString() { return "%s:%.3s:%+1.2f".formatted( 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 2deb57b5..7b79bc15 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 @@ -7,13 +7,23 @@ import lombok.NoArgsConstructor; import lombok.Setter; import net.hostsharing.hsadminng.errors.DisplayAs; import net.hostsharing.hsadminng.hs.office.membership.HsOfficeMembershipEntity; -import net.hostsharing.hsadminng.rbac.generator.RbacSpec; import net.hostsharing.hsadminng.persistence.BaseEntity; +import net.hostsharing.hsadminng.rbac.generator.RbacSpec; import net.hostsharing.hsadminng.rbac.generator.RbacSpec.SQL; import net.hostsharing.hsadminng.repr.Stringify; import net.hostsharing.hsadminng.repr.Stringifyable; -import jakarta.persistence.*; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.EnumType; +import jakarta.persistence.Enumerated; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.Id; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.ManyToOne; +import jakarta.persistence.OneToOne; +import jakarta.persistence.Table; +import jakarta.persistence.Version; import java.io.IOException; import java.time.LocalDate; import java.util.UUID; -- 2.39.5 From c56d06072a1541c56e3f103f513d4ee9108a2333 Mon Sep 17 00:00:00 2001 From: Michael Hoennig Date: Tue, 14 Jan 2025 11:32:24 +0100 Subject: [PATCH 12/35] add roleId(...) to HsOfficeMembershipEntity --- .../hs/office/membership/HsOfficeMembershipEntity.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) 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 3b0f58de..a1741926 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 @@ -13,6 +13,7 @@ import net.hostsharing.hsadminng.persistence.BaseEntity; import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerEntity; import net.hostsharing.hsadminng.rbac.generator.RbacSpec; import net.hostsharing.hsadminng.rbac.generator.RbacSpec.SQL; +import net.hostsharing.hsadminng.rbac.role.WithRoleId; import net.hostsharing.hsadminng.repr.Stringify; import net.hostsharing.hsadminng.repr.Stringifyable; import org.hibernate.annotations.Type; @@ -63,7 +64,7 @@ import static net.hostsharing.hsadminng.repr.Stringify.stringify; @NoArgsConstructor @AllArgsConstructor @DisplayAs("Membership") -public class HsOfficeMembershipEntity implements BaseEntity, Stringifyable { +public class HsOfficeMembershipEntity implements BaseEntity, Stringifyable, WithRoleId { public static final String MEMBER_NUMBER_TAG = "M-"; public static final String TWO_DECIMAL_DIGITS = "^([0-9]{2})$"; -- 2.39.5 From d98c8ef8d3ddc9cf9415510dc6be71c014614271 Mon Sep 17 00:00:00 2001 From: Michael Hoennig Date: Tue, 14 Jan 2025 11:33:13 +0100 Subject: [PATCH 13/35] there can be multiple INSERT permissions for a single targetObject --- .../hsadminng/rbac/grant/RbacGrantsDiagramService.java | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/main/java/net/hostsharing/hsadminng/rbac/grant/RbacGrantsDiagramService.java b/src/main/java/net/hostsharing/hsadminng/rbac/grant/RbacGrantsDiagramService.java index 64a2d33e..6a15464d 100644 --- a/src/main/java/net/hostsharing/hsadminng/rbac/grant/RbacGrantsDiagramService.java +++ b/src/main/java/net/hostsharing/hsadminng/rbac/grant/RbacGrantsDiagramService.java @@ -94,12 +94,14 @@ public class RbacGrantsDiagramService { } public String allGrantsFrom(final UUID targetObject, final String op, final EnumSet includes) { - final var refUuid = (UUID) em.createNativeQuery("SELECT uuid FROM rbac.permission WHERE objectuuid=:targetObject AND op=:op") + final var graph = new LimitedHashSet(); + + @SuppressWarnings("unchecked") + final var refUuids = (List) em.createNativeQuery("SELECT uuid FROM rbac.permission WHERE objectuuid=:targetObject AND op=:op", List.class) .setParameter("targetObject", targetObject) .setParameter("op", op) - .getSingleResult(); - final var graph = new LimitedHashSet(); - traverseGrantsFrom(graph, refUuid, includes); + .getResultList(); + refUuids.forEach(refUuid -> traverseGrantsFrom(graph, refUuid, includes)); return toMermaidFlowchart(graph, includes); } -- 2.39.5 From e12a33411e7262500bc94e76cf292edaac6fba59 Mon Sep 17 00:00:00 2001 From: Michael Hoennig Date: Tue, 14 Jan 2025 11:33:56 +0100 Subject: [PATCH 14/35] partner JoinFormula in HsOfficeDebitorEntity using real hs_office.partner --- .../hsadminng/hs/office/debitor/HsOfficeDebitorEntity.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 6181c6f4..0f0fc9cf 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 @@ -87,7 +87,7 @@ public class HsOfficeDebitorEntity implements BaseEntity, value = """ ( SELECT DISTINCT partner.uuid - FROM hs_office.partner_rv partner + FROM hs_office.partner partner JOIN hs_office.relation dRel ON dRel.uuid = debitorreluuid AND dRel.type = 'DEBITOR' JOIN hs_office.relation pRel -- 2.39.5 From 575fe9f88a411f19ca70f256e1f6b156e08d285f Mon Sep 17 00:00:00 2001 From: Michael Hoennig Date: Tue, 14 Jan 2025 13:44:24 +0100 Subject: [PATCH 15/35] refactor HsOfficeDebitorController --- .../debitor/HsOfficeDebitorController.java | 34 ++++++++----------- .../office/debitor/HsOfficeDebitorEntity.java | 2 +- ...OfficeDebitorControllerAcceptanceTest.java | 2 +- 3 files changed, 17 insertions(+), 21 deletions(-) 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 70efafd4..ee8909c3 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 @@ -105,26 +105,10 @@ public class HsOfficeDebitorController implements HsOfficeDebitorsApi { "ERROR: [400] debitorRel.mark must be null"); final var entityToSave = mapper.map(body, HsOfficeDebitorEntity.class, RESOURCE_TO_ENTITY_POSTMAPPER); - if (body.getDebitorRel() != null) { // FIXME: move this into RESOURCE_TO_ENTITY_POSTMAPPER - final var debitorRel = entityToSave.getDebitorRel(); - debitorRel.setType(DEBITOR); - entityValidator.validateEntityExists("debitorRel.anchorUuid", debitorRel.getAnchor()); - entityValidator.validateEntityExists("debitorRel.holderUuid", debitorRel.getHolder()); - entityValidator.validateEntityExists("debitorRel.contactUuid", debitorRel.getContact()); - entityToSave.setDebitorRel(realRelRepo.save(debitorRel)); - } else { - final var debitorRelOptional = realRelRepo.findByUuid(body.getDebitorRelUuid()); - debitorRelOptional.ifPresentOrElse( - debitorRel -> {entityToSave.setDebitorRel(realRelRepo.save(debitorRel));}, - () -> { - throw new ValidationException( - "Unable to find RealRelation by debitorRelUuid: " + body.getDebitorRelUuid()); - }); - } - final var savedEntity = debitorRepo.save(entityToSave); - em.flush(); // FIXME: necessary? - em.refresh(savedEntity); + final var savedEntity = debitorRepo.save(entityToSave).load(); +// em.flush(); // FIXME: necessary? +// em.refresh(savedEntity); final var uri = MvcUriComponentsBuilder.fromController(getClass()) @@ -219,11 +203,23 @@ public class HsOfficeDebitorController implements HsOfficeDebitorsApi { "debitorRel.contact.uuid", resource.getDebitorRel().getContactUuid(), realContactRepo::findByUuid)) .build()); entity.setDebitorRel(debitorRel); + } else { + final var debitorRelOptional = realRelRepo.findByUuid(resource.getDebitorRelUuid()); + debitorRelOptional.ifPresentOrElse( + debitorRel -> { + entity.setDebitorRel(realRelRepo.save(debitorRel)); + }, + () -> { + throw new ValidationException( + "Unable to find debitorRel.uuid: " + resource.getDebitorRelUuid()); + }); } + if (resource.getRefundBankAccountUuid() != null) { entity.setRefundBankAccount(resolve( "refundBankAccount.uuid", resource.getRefundBankAccountUuid(), bankAccountRepo::findByUuid)); } + }; final BiConsumer ENTITY_TO_RESOURCE_POSTMAPPER = (entity, resource) -> { 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 0f0fc9cf..b27f1866 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 @@ -132,7 +132,7 @@ public class HsOfficeDebitorEntity implements BaseEntity, @Override public HsOfficeDebitorEntity load() { BaseEntity.super.load(); - if (partner != null) { + if (partner != null) { // FIXME: should not happen partner.load(); } debitorRel.load(); 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 206df39d..38a6b24f 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 @@ -496,7 +496,7 @@ class HsOfficeDebitorControllerAcceptanceTest extends ContextBasedTestWithCleanu .post("http://localhost/api/hs/office/debitors") .then().log().all().assertThat() .statusCode(400) - .body("message", is("ERROR: [400] Unable to find RealRelation by debitorRelUuid: 00000000-0000-0000-0000-000000000000")); + .body("message", is("ERROR: [400] Unable to find debitorRel.uuid: 00000000-0000-0000-0000-000000000000")); // @formatter:on } } -- 2.39.5 From b3391578ec1fb93d53b055302c505b9198650727 Mon Sep 17 00:00:00 2001 From: Michael Hoennig Date: Tue, 14 Jan 2025 14:32:34 +0100 Subject: [PATCH 16/35] getting rid of some FIXMEs --- .../asset/validators/HsUnixUserHostingAssetValidator.java | 2 -- .../hs/office/debitor/HsOfficeDebitorController.java | 4 +--- .../net/hostsharing/hsadminng/persistence/BaseEntity.java | 7 +++++++ 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/main/java/net/hostsharing/hsadminng/hs/hosting/asset/validators/HsUnixUserHostingAssetValidator.java b/src/main/java/net/hostsharing/hsadminng/hs/hosting/asset/validators/HsUnixUserHostingAssetValidator.java index 9f2ac336..024866c2 100644 --- a/src/main/java/net/hostsharing/hsadminng/hs/hosting/asset/validators/HsUnixUserHostingAssetValidator.java +++ b/src/main/java/net/hostsharing/hsadminng/hs/hosting/asset/validators/HsUnixUserHostingAssetValidator.java @@ -6,7 +6,6 @@ import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType; import net.hostsharing.hsadminng.hs.validation.PropertiesProvider; import jakarta.persistence.EntityManager; -import jakarta.persistence.FlushModeType; import java.util.regex.Pattern; import static net.hostsharing.hsadminng.hs.validation.BooleanProperty.booleanProperty; @@ -54,7 +53,6 @@ class HsUnixUserHostingAssetValidator extends HostingAssetEntityValidator { } private static Integer computeUserId(final EntityManager em, final PropertiesProvider propertiesProvider) { - em.setFlushMode(FlushModeType.COMMIT); // FIXME: check and remove or reset final Object result = em.createNativeQuery("SELECT nextval('hs_hosting.asset_unixuser_system_id_seq')", Integer.class) .getSingleResult(); return (Integer) result; 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 ee8909c3..0ac686ee 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 @@ -106,9 +106,7 @@ public class HsOfficeDebitorController implements HsOfficeDebitorsApi { final var entityToSave = mapper.map(body, HsOfficeDebitorEntity.class, RESOURCE_TO_ENTITY_POSTMAPPER); - final var savedEntity = debitorRepo.save(entityToSave).load(); -// em.flush(); // FIXME: necessary? -// em.refresh(savedEntity); + final var savedEntity = debitorRepo.save(entityToSave).reload(em); final var uri = MvcUriComponentsBuilder.fromController(getClass()) diff --git a/src/main/java/net/hostsharing/hsadminng/persistence/BaseEntity.java b/src/main/java/net/hostsharing/hsadminng/persistence/BaseEntity.java index b3e5a535..aede0d7d 100644 --- a/src/main/java/net/hostsharing/hsadminng/persistence/BaseEntity.java +++ b/src/main/java/net/hostsharing/hsadminng/persistence/BaseEntity.java @@ -3,6 +3,7 @@ package net.hostsharing.hsadminng.persistence; import org.hibernate.Hibernate; +import jakarta.persistence.EntityManager; import java.util.UUID; public interface BaseEntity> { @@ -15,4 +16,10 @@ public interface BaseEntity> { //noinspection unchecked return (T) this; }; + + default T reload(final EntityManager em) { + em.flush(); + em.refresh(this); + return load(); + } } -- 2.39.5 From b094f1d8ec9949cea7a25b8968c6e124b2ad8c92 Mon Sep 17 00:00:00 2001 From: Michael Hoennig Date: Tue, 14 Jan 2025 15:02:01 +0100 Subject: [PATCH 17/35] formatting --- .../HsOfficeDebitorControllerAcceptanceTest.java | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) 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 38a6b24f..9d0425c4 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 @@ -703,7 +703,7 @@ class HsOfficeDebitorControllerAcceptanceTest extends ContextBasedTestWithCleanu // @formatter:on RestAssured // @formatter:off - .given() + .given() .header("current-subject", "superuser-alex@hostsharing.net") .header("assumed-roles", givenDebitor.getDebitorRel().getContact().roleId(ADMIN) ) .contentType(ContentType.JSON) @@ -713,12 +713,12 @@ class HsOfficeDebitorControllerAcceptanceTest extends ContextBasedTestWithCleanu } """) .port(port) - .when() - .patch("http://localhost/api/hs/office/debitors/" + givenDebitor.getUuid()) - .then().log().all().assertThat() - .statusCode(403) - .body("message", containsString("ERROR: [403] Subject")) - .body("message", containsString("is not allowed to update hs_office.debitor uuid ")); + .when() + .patch("http://localhost/api/hs/office/debitors/" + givenDebitor.getUuid()) + .then().log().all().assertThat() + .statusCode(403) + .body("message", containsString("ERROR: [403] Subject")) + .body("message", containsString("is not allowed to update hs_office.debitor uuid ")); } } -- 2.39.5 From 35ddf85269eda9d5e1f1fb277a33af195a1ce425 Mon Sep 17 00:00:00 2001 From: Michael Hoennig Date: Tue, 14 Jan 2025 15:44:44 +0100 Subject: [PATCH 18/35] use reload where possible --- .../hsadminng/hs/office/debitor/HsOfficeDebitorController.java | 2 +- .../hsadminng/hs/office/debitor/HsOfficeDebitorEntity.java | 2 +- .../office/debitor/HsOfficeDebitorControllerAcceptanceTest.java | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) 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 0ac686ee..78b8082d 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 @@ -179,7 +179,7 @@ public class HsOfficeDebitorController implements HsOfficeDebitorsApi { context.define(currentSubject, assumedRoles); - final var current = debitorRepo.findByUuid(debitorUuid).orElseThrow().load(); + final var current = debitorRepo.findByUuid(debitorUuid).orElseThrow().reload(em); new HsOfficeDebitorEntityPatcher(em, current).apply(body); 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 b27f1866..374e2939 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 @@ -89,7 +89,7 @@ public class HsOfficeDebitorEntity implements BaseEntity, SELECT DISTINCT partner.uuid FROM hs_office.partner partner JOIN hs_office.relation dRel - ON dRel.uuid = debitorreluuid AND dRel.type = 'DEBITOR' + ON dRel.uuid = debitorRelUuid AND dRel.type = 'DEBITOR' JOIN hs_office.relation pRel ON pRel.uuid = partner.partnerRelUuid AND pRel.type = 'PARTNER' WHERE pRel.holderUuid = dRel.anchorUuid 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 9d0425c4..84d6b280 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 @@ -803,7 +803,7 @@ class HsOfficeDebitorControllerAcceptanceTest extends ContextBasedTestWithCleanu .vatReverseCharge(false) .build(); - return debitorRepo.save(newDebitor).load(); + return debitorRepo.save(newDebitor).reload(em); }).assertSuccessful().returnedValue(); } -- 2.39.5 From 6ef8294b7e3d98e116a246065fc71339d1c215a5 Mon Sep 17 00:00:00 2001 From: Michael Hoennig Date: Tue, 14 Jan 2025 15:46:00 +0100 Subject: [PATCH 19/35] rename HsOfficePartnerEntity to HsOfficePartnerRbacEntity --- .../office/debitor/HsOfficeDebitorEntity.java | 6 ++-- .../HsOfficeMembershipController.java | 8 ++--- .../membership/HsOfficeMembershipEntity.java | 4 +-- .../partner/HsOfficePartnerController.java | 12 +++---- .../partner/HsOfficePartnerEntityPatcher.java | 4 +-- ...ty.java => HsOfficePartnerRbacEntity.java} | 10 +++--- ...ava => HsOfficePartnerRbacRepository.java} | 25 ++++----------- .../hs/migration/BaseOfficeDataImport.java | 6 ++-- ...opAssetsTransactionControllerRestTest.java | 6 ++-- ...OfficeDebitorControllerAcceptanceTest.java | 4 +-- .../HsOfficeDebitorEntityUnitTest.java | 12 +++---- ...fficeDebitorRepositoryIntegrationTest.java | 4 +-- ...iceMembershipControllerAcceptanceTest.java | 4 +-- .../HsOfficeMembershipControllerRestTest.java | 10 +++--- .../HsOfficeMembershipEntityUnitTest.java | 4 +-- ...ceMembershipRepositoryIntegrationTest.java | 4 +-- ...OfficePartnerControllerAcceptanceTest.java | 8 ++--- .../HsOfficePartnerControllerRestTest.java | 6 ++-- .../HsOfficePartnerEntityPatcherUnitTest.java | 10 +++--- .../HsOfficePartnerEntityUnitTest.java | 4 +-- ...fficePartnerRepositoryIntegrationTest.java | 32 +++++++++---------- .../office/partner/TestHsOfficePartner.java | 6 ++-- 22 files changed, 88 insertions(+), 101 deletions(-) rename src/main/java/net/hostsharing/hsadminng/hs/office/partner/{HsOfficePartnerEntity.java => HsOfficePartnerRbacEntity.java} (92%) rename src/main/java/net/hostsharing/hsadminng/hs/office/partner/{HsOfficePartnerRepository.java => HsOfficePartnerRbacRepository.java} (57%) 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 374e2939..32d9038f 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,7 +7,7 @@ import lombok.NoArgsConstructor; import lombok.Setter; import net.hostsharing.hsadminng.errors.DisplayAs; import net.hostsharing.hsadminng.hs.office.bankaccount.HsOfficeBankAccountEntity; -import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerEntity; +import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerRbacEntity; import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelation; import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationRealEntity; import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationRbacEntity; @@ -96,7 +96,7 @@ public class HsOfficeDebitorEntity implements BaseEntity, ) """) @NotFound(action = NotFoundAction.IGNORE) // TODO.impl: map a simplified raw-PartnerEntity, just for the partner-number - private HsOfficePartnerEntity partner; + private HsOfficePartnerRbacEntity partner; @Column(name = "debitornumbersuffix", length = 2) @Pattern(regexp = TWO_DECIMAL_DIGITS) @@ -145,7 +145,7 @@ public class HsOfficeDebitorEntity implements BaseEntity, public String getTaggedDebitorNumber() { return ofNullable(partner) .filter(partner -> debitorNumberSuffix != null) - .map(HsOfficePartnerEntity::getPartnerNumber) + .map(HsOfficePartnerRbacEntity::getPartnerNumber) .map(partnerNumber -> DEBITOR_NUMBER_TAG + partnerNumber + debitorNumberSuffix) .orElse(null); } 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 778d12b9..0d1b9110 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 @@ -6,8 +6,8 @@ import net.hostsharing.hsadminng.hs.office.generated.api.v1.api.HsOfficeMembersh import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeMembershipInsertResource; import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeMembershipPatchResource; import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeMembershipResource; -import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerEntity; -import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerRepository; +import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerRbacEntity; +import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerRbacRepository; import net.hostsharing.hsadminng.mapper.StrictMapper; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.ResponseEntity; @@ -33,7 +33,7 @@ public class HsOfficeMembershipController implements HsOfficeMembershipsApi { private StrictMapper mapper; @Autowired - private HsOfficePartnerRepository partnerRepo; + private HsOfficePartnerRbacRepository partnerRepo; @Autowired private HsOfficeMembershipRepository membershipRepo; @@ -52,7 +52,7 @@ public class HsOfficeMembershipController implements HsOfficeMembershipsApi { final var entities = partnerNumber != null ? membershipRepo.findMembershipsByPartnerNumber( - cropTag(HsOfficePartnerEntity.PARTNER_NUMBER_TAG, partnerNumber)) + cropTag(HsOfficePartnerRbacEntity.PARTNER_NUMBER_TAG, partnerNumber)) : partnerUuid != null ? membershipRepo.findMembershipsByPartnerUuid(partnerUuid) : membershipRepo.findAll(); 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 a1741926..08c7ae93 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 @@ -10,7 +10,7 @@ import lombok.Setter; import net.hostsharing.hsadminng.errors.DisplayAs; import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationRbacEntity; import net.hostsharing.hsadminng.persistence.BaseEntity; -import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerEntity; +import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerRbacEntity; import net.hostsharing.hsadminng.rbac.generator.RbacSpec; import net.hostsharing.hsadminng.rbac.generator.RbacSpec.SQL; import net.hostsharing.hsadminng.rbac.role.WithRoleId; @@ -85,7 +85,7 @@ public class HsOfficeMembershipEntity implements BaseEntity ENTITY_TO_RESOURCE_POSTMAPPER = (entity, resource) -> { + final BiConsumer ENTITY_TO_RESOURCE_POSTMAPPER = (entity, resource) -> { resource.setPartnerNumber(entity.getTaggedPartnerNumber()); }; } diff --git a/src/main/java/net/hostsharing/hsadminng/hs/office/partner/HsOfficePartnerEntityPatcher.java b/src/main/java/net/hostsharing/hsadminng/hs/office/partner/HsOfficePartnerEntityPatcher.java index b01ccc6b..ecf8adc9 100644 --- a/src/main/java/net/hostsharing/hsadminng/hs/office/partner/HsOfficePartnerEntityPatcher.java +++ b/src/main/java/net/hostsharing/hsadminng/hs/office/partner/HsOfficePartnerEntityPatcher.java @@ -9,10 +9,10 @@ import jakarta.persistence.EntityManager; class HsOfficePartnerEntityPatcher implements EntityPatcher { private final EntityManager em; - private final HsOfficePartnerEntity entity; + private final HsOfficePartnerRbacEntity entity; HsOfficePartnerEntityPatcher( final EntityManager em, - final HsOfficePartnerEntity entity) { + final HsOfficePartnerRbacEntity entity) { this.em = em; this.entity = entity; } diff --git a/src/main/java/net/hostsharing/hsadminng/hs/office/partner/HsOfficePartnerEntity.java b/src/main/java/net/hostsharing/hsadminng/hs/office/partner/HsOfficePartnerRbacEntity.java similarity index 92% rename from src/main/java/net/hostsharing/hsadminng/hs/office/partner/HsOfficePartnerEntity.java rename to src/main/java/net/hostsharing/hsadminng/hs/office/partner/HsOfficePartnerRbacEntity.java index 3575b24b..35f9c4c6 100644 --- a/src/main/java/net/hostsharing/hsadminng/hs/office/partner/HsOfficePartnerEntity.java +++ b/src/main/java/net/hostsharing/hsadminng/hs/office/partner/HsOfficePartnerRbacEntity.java @@ -43,12 +43,12 @@ import static net.hostsharing.hsadminng.repr.Stringify.stringify; @NoArgsConstructor @AllArgsConstructor @DisplayAs("Partner") -public class HsOfficePartnerEntity implements Stringifyable, BaseEntity { +public class HsOfficePartnerRbacEntity implements Stringifyable, BaseEntity { public static final String PARTNER_NUMBER_TAG = "P-"; - private static Stringify stringify = stringify(HsOfficePartnerEntity.class, "partner") - .withIdProp(HsOfficePartnerEntity::toShortString) + private static Stringify stringify = stringify(HsOfficePartnerRbacEntity.class, "partner") + .withIdProp(HsOfficePartnerRbacEntity::toShortString) .withProp(p -> ofNullable(p.getPartnerRel()) .map(HsOfficeRelation::getHolder) .map(HsOfficePerson::toShortString) @@ -79,7 +79,7 @@ public class HsOfficePartnerEntity implements Stringifyable, BaseEntity { +public interface HsOfficePartnerRbacRepository extends Repository { @Timed("app.office.partners.repo.findByUuid") - Optional findByUuid(UUID id); + Optional findByUuid(UUID id); @Timed("app.office.partners.repo.findAll") - List findAll(); // TODO.refa: move to a repo in test sources + List findAll(); // TODO.refa: move to a repo in test sources -// @Query(""" -// SELECT partner FROM HsOfficePartnerEntity partner -// JOIN HsOfficeRelationRealEntity rel ON rel.uuid = partner.partnerRel.uuid -// JOIN HsOfficeContactRealEntity contact ON contact.uuid = rel.contact.uuid -// JOIN HsOfficePersonRealEntity person ON person.uuid = rel.holder.uuid -// LEFT JOIN HsOfficePartnerDetailsEntity details ON partner.details.uuid = details.uuid -// WHERE :name is null -// OR (details IS NOT NULL AND details.birthName like concat(cast(:name as text), '%')) -// OR contact.caption like concat(cast(:name as text), '%') -// OR person.tradeName like concat(cast(:name as text), '%') -// OR person.givenName like concat(cast(:name as text), '%') -// OR person.familyName like concat(cast(:name as text), '%') -// """) @Query(value = """ select partner.uuid, partner.detailsuuid, partner.partnernumber, partner.partnerreluuid, partner.version from hs_office.partner_rv partner @@ -44,13 +31,13 @@ public interface HsOfficePartnerRepository extends Repository findPartnerByOptionalNameLike(String name); + List findPartnerByOptionalNameLike(String name); @Timed("app.office.partners.repo.findPartnerByPartnerNumber") - Optional findPartnerByPartnerNumber(Integer partnerNumber); + Optional findPartnerByPartnerNumber(Integer partnerNumber); @Timed("app.office.partners.repo.save") - HsOfficePartnerEntity save(final HsOfficePartnerEntity entity); + HsOfficePartnerRbacEntity save(final HsOfficePartnerRbacEntity entity); @Timed("app.office.partners.repo.count") long count(); diff --git a/src/test/java/net/hostsharing/hsadminng/hs/migration/BaseOfficeDataImport.java b/src/test/java/net/hostsharing/hsadminng/hs/migration/BaseOfficeDataImport.java index da89e268..35547e1d 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/migration/BaseOfficeDataImport.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/migration/BaseOfficeDataImport.java @@ -10,7 +10,7 @@ import net.hostsharing.hsadminng.hs.office.debitor.HsOfficeDebitorEntity; import net.hostsharing.hsadminng.hs.office.membership.HsOfficeMembershipEntity; import net.hostsharing.hsadminng.hs.office.membership.HsOfficeMembershipStatus; import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerDetailsEntity; -import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerEntity; +import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerRbacEntity; import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonRealEntity; import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonType; import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelation; @@ -84,7 +84,7 @@ public abstract class BaseOfficeDataImport extends CsvDataImport { static Map contacts = new WriteOnceMap<>(); static Map persons = new WriteOnceMap<>(); - static Map partners = new WriteOnceMap<>(); + static Map partners = new WriteOnceMap<>(); static Map debitors = new WriteOnceMap<>(); static Map memberships = new WriteOnceMap<>(); @@ -743,7 +743,7 @@ public abstract class BaseOfficeDataImport extends CsvDataImport { null // is set during contacts import depending on assigned roles ); - final var partner = HsOfficePartnerEntity.builder() + final var partner = HsOfficePartnerRbacEntity.builder() .partnerNumber(rec.getInteger("member_id")) .details(HsOfficePartnerDetailsEntity.builder().build()) .partnerRel(partnerRel) diff --git a/src/test/java/net/hostsharing/hsadminng/hs/office/coopassets/HsOfficeCoopAssetsTransactionControllerRestTest.java b/src/test/java/net/hostsharing/hsadminng/hs/office/coopassets/HsOfficeCoopAssetsTransactionControllerRestTest.java index 3e657a30..1e2cfa63 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/office/coopassets/HsOfficeCoopAssetsTransactionControllerRestTest.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/office/coopassets/HsOfficeCoopAssetsTransactionControllerRestTest.java @@ -4,7 +4,7 @@ import net.hostsharing.hsadminng.config.JsonObjectMapperConfiguration; import net.hostsharing.hsadminng.context.Context; import net.hostsharing.hsadminng.hs.office.membership.HsOfficeMembershipEntity; import net.hostsharing.hsadminng.hs.office.membership.HsOfficeMembershipRepository; -import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerEntity; +import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerRbacEntity; import net.hostsharing.hsadminng.mapper.StrictMapper; import net.hostsharing.hsadminng.persistence.EntityManagerWrapper; import net.hostsharing.hsadminng.rbac.test.JsonBuilder; @@ -67,7 +67,7 @@ class HsOfficeCoopAssetsTransactionControllerRestTest { private static final String ORIGIN_MEMBER_NUMBER = "M-1111100"; public final HsOfficeMembershipEntity ORIGIN_TARGET_MEMBER_ENTITY = HsOfficeMembershipEntity.builder() .uuid(ORIGIN_MEMBERSHIP_UUID) - .partner(HsOfficePartnerEntity.builder() + .partner(HsOfficePartnerRbacEntity.builder() .partnerNumber(partnerNumberOf(ORIGIN_MEMBER_NUMBER)) .build()) .memberNumberSuffix(suffixOf(ORIGIN_MEMBER_NUMBER)) @@ -77,7 +77,7 @@ class HsOfficeCoopAssetsTransactionControllerRestTest { private static final String AVAILABLE_TARGET_MEMBER_NUMBER = "M-1234500"; public final HsOfficeMembershipEntity AVAILABLE_MEMBER_ENTITY = HsOfficeMembershipEntity.builder() .uuid(AVAILABLE_TARGET_MEMBERSHIP_UUID) - .partner(HsOfficePartnerEntity.builder() + .partner(HsOfficePartnerRbacEntity.builder() .partnerNumber(partnerNumberOf(AVAILABLE_TARGET_MEMBER_NUMBER)) .build()) .memberNumberSuffix(suffixOf(AVAILABLE_TARGET_MEMBER_NUMBER)) 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 84d6b280..98be1755 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 @@ -6,7 +6,7 @@ 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.HsOfficeContactRealRepository; -import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerRepository; +import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerRbacRepository; import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonRealRepository; import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationRealEntity; import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationRealRepository; @@ -58,7 +58,7 @@ class HsOfficeDebitorControllerAcceptanceTest extends ContextBasedTestWithCleanu HsOfficeDebitorRepository debitorRepo; @Autowired - HsOfficePartnerRepository partnerRepo; + HsOfficePartnerRbacRepository partnerRepo; @Autowired HsOfficeContactRealRepository contactRealRepo; diff --git a/src/test/java/net/hostsharing/hsadminng/hs/office/debitor/HsOfficeDebitorEntityUnitTest.java b/src/test/java/net/hostsharing/hsadminng/hs/office/debitor/HsOfficeDebitorEntityUnitTest.java index 57351efe..023fcc6b 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/office/debitor/HsOfficeDebitorEntityUnitTest.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/office/debitor/HsOfficeDebitorEntityUnitTest.java @@ -1,7 +1,7 @@ package net.hostsharing.hsadminng.hs.office.debitor; import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactRealEntity; -import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerEntity; +import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerRbacEntity; import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonRealEntity; import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonType; import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationRealEntity; @@ -30,7 +30,7 @@ class HsOfficeDebitorEntityUnitTest { .debitorNumberSuffix("67") .debitorRel(givenDebitorRel) .defaultPrefix("som") - .partner(HsOfficePartnerEntity.builder() + .partner(HsOfficePartnerRbacEntity.builder() .partnerNumber(12345) .build()) .build(); @@ -45,7 +45,7 @@ class HsOfficeDebitorEntityUnitTest { final var given = HsOfficeDebitorEntity.builder() .debitorRel(givenDebitorRel) .debitorNumberSuffix("67") - .partner(HsOfficePartnerEntity.builder() + .partner(HsOfficePartnerRbacEntity.builder() .partnerNumber(12345) .build()) .build(); @@ -60,7 +60,7 @@ class HsOfficeDebitorEntityUnitTest { final var given = HsOfficeDebitorEntity.builder() .debitorRel(givenDebitorRel) .debitorNumberSuffix("67") - .partner(HsOfficePartnerEntity.builder() + .partner(HsOfficePartnerRbacEntity.builder() .partnerNumber(12345) .build()) .build(); @@ -88,7 +88,7 @@ class HsOfficeDebitorEntityUnitTest { final var given = HsOfficeDebitorEntity.builder() .debitorRel(givenDebitorRel) .debitorNumberSuffix("67") - .partner(HsOfficePartnerEntity.builder().build()) + .partner(HsOfficePartnerRbacEntity.builder().build()) .build(); final var result = given.getTaggedDebitorNumber(); @@ -101,7 +101,7 @@ class HsOfficeDebitorEntityUnitTest { final var given = HsOfficeDebitorEntity.builder() .debitorRel(givenDebitorRel) .debitorNumberSuffix(null) - .partner(HsOfficePartnerEntity.builder() + .partner(HsOfficePartnerRbacEntity.builder() .partnerNumber(12345) .build()) .build(); 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 c461a8ba..c3537f74 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 @@ -3,7 +3,7 @@ package net.hostsharing.hsadminng.hs.office.debitor; import net.hostsharing.hsadminng.context.Context; import net.hostsharing.hsadminng.hs.office.bankaccount.HsOfficeBankAccountRepository; import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactRealRepository; -import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerRepository; +import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerRbacRepository; import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonRealRepository; import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelation; import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationRealEntity; @@ -48,7 +48,7 @@ class HsOfficeDebitorRepositoryIntegrationTest extends ContextBasedTestWithClean HsOfficeDebitorRepository debitorRepo; @Autowired - HsOfficePartnerRepository partnerRepo; + HsOfficePartnerRbacRepository partnerRepo; @Autowired HsOfficeContactRealRepository contactRealRepo; diff --git a/src/test/java/net/hostsharing/hsadminng/hs/office/membership/HsOfficeMembershipControllerAcceptanceTest.java b/src/test/java/net/hostsharing/hsadminng/hs/office/membership/HsOfficeMembershipControllerAcceptanceTest.java index 3c67b2cd..ed7a8925 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/office/membership/HsOfficeMembershipControllerAcceptanceTest.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/office/membership/HsOfficeMembershipControllerAcceptanceTest.java @@ -5,7 +5,7 @@ import io.restassured.RestAssured; import io.restassured.http.ContentType; import net.hostsharing.hsadminng.HsadminNgApplication; import net.hostsharing.hsadminng.context.Context; -import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerRepository; +import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerRbacRepository; import net.hostsharing.hsadminng.rbac.test.ContextBasedTestWithCleanup; import net.hostsharing.hsadminng.rbac.test.JpaAttempt; import net.hostsharing.hsadminng.config.DisableSecurityConfig; @@ -54,7 +54,7 @@ class HsOfficeMembershipControllerAcceptanceTest extends ContextBasedTestWithCle HsOfficeMembershipRepository membershipRepo; @Autowired - HsOfficePartnerRepository partnerRepo; + HsOfficePartnerRbacRepository partnerRepo; @Autowired JpaAttempt jpaAttempt; 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 216b0298..54ffbd85 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,8 +2,8 @@ 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.partner.HsOfficePartnerEntity; -import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerRepository; +import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerRbacEntity; +import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerRbacRepository; import net.hostsharing.hsadminng.mapper.StrictMapper; import net.hostsharing.hsadminng.persistence.EntityManagerWrapper; import net.hostsharing.hsadminng.config.DisableSecurityConfig; @@ -39,7 +39,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. @ActiveProfiles("test") public class HsOfficeMembershipControllerRestTest { - private static final HsOfficePartnerEntity PARTNER_12345 = HsOfficePartnerEntity.builder() + private static final HsOfficePartnerRbacEntity PARTNER_12345 = HsOfficePartnerRbacEntity.builder() .partnerNumber(12345) .build(); public static final HsOfficeMembershipEntity MEMBERSHIP_1234501 = HsOfficeMembershipEntity.builder() @@ -77,7 +77,7 @@ public class HsOfficeMembershipControllerRestTest { HsOfficeCoopAssetsTransactionRepository coopAssetsTransactionRepo; @MockitoBean - HsOfficePartnerRepository partnerRepo; + HsOfficePartnerRbacRepository partnerRepo; @MockitoBean HsOfficeMembershipRepository membershipRepo; @@ -256,7 +256,7 @@ public class HsOfficeMembershipControllerRestTest { // given final var givenPartnerUuid = UUID.randomUUID(); - when(em.find(HsOfficePartnerEntity.class, givenPartnerUuid)).thenReturn(null); + when(em.find(HsOfficePartnerRbacEntity.class, givenPartnerUuid)).thenReturn(null); // when mockMvc.perform(MockMvcRequestBuilders diff --git a/src/test/java/net/hostsharing/hsadminng/hs/office/membership/HsOfficeMembershipEntityUnitTest.java b/src/test/java/net/hostsharing/hsadminng/hs/office/membership/HsOfficeMembershipEntityUnitTest.java index 6d2b13be..49219290 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/office/membership/HsOfficeMembershipEntityUnitTest.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/office/membership/HsOfficeMembershipEntityUnitTest.java @@ -1,7 +1,7 @@ package net.hostsharing.hsadminng.hs.office.membership; import io.hypersistence.utils.hibernate.type.range.Range; -import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerEntity; +import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerRbacEntity; import net.hostsharing.hsadminng.rbac.generator.RbacViewMermaidFlowchartGenerator; import org.junit.jupiter.api.Test; @@ -57,7 +57,7 @@ class HsOfficeMembershipEntityUnitTest { @Test void getMemberNumberWithoutPartnerNumberButWithSuffix() { - givenMembership.setPartner(HsOfficePartnerEntity.builder().build()); + givenMembership.setPartner(HsOfficePartnerRbacEntity.builder().build()); final var result = givenMembership.getMemberNumber(); assertThat(result).isEqualTo(null); } 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 13c5396a..04be5edd 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 @@ -3,7 +3,7 @@ package net.hostsharing.hsadminng.hs.office.membership; import io.hypersistence.utils.hibernate.type.range.Range; import net.hostsharing.hsadminng.context.Context; import net.hostsharing.hsadminng.hs.office.debitor.HsOfficeDebitorRepository; -import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerRepository; +import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerRbacRepository; import net.hostsharing.hsadminng.rbac.test.ContextBasedTestWithCleanup; import net.hostsharing.hsadminng.rbac.grant.RawRbacGrantRepository; import net.hostsharing.hsadminng.rbac.role.RawRbacRoleRepository; @@ -37,7 +37,7 @@ class HsOfficeMembershipRepositoryIntegrationTest extends ContextBasedTestWithCl HsOfficeMembershipRepository membershipRepo; @Autowired - HsOfficePartnerRepository partnerRepo; + HsOfficePartnerRbacRepository partnerRepo; @Autowired HsOfficeDebitorRepository debitorRepo; 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 54a4baf2..8bfc7009 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 @@ -42,7 +42,7 @@ class HsOfficePartnerControllerAcceptanceTest extends ContextBasedTestWithCleanu private Integer port; @Autowired - HsOfficePartnerRepository partnerRepo; + HsOfficePartnerRbacRepository partnerRepo; @Autowired HsOfficeRelationRealRepository relationRepo; @@ -541,12 +541,12 @@ class HsOfficePartnerControllerAcceptanceTest extends ContextBasedTestWithCleanu return partnerRel; }).assertSuccessful().returnedValue(); } - private HsOfficePartnerEntity givenSomeTemporaryPartnerBessler(final Integer partnerNumber) { + private HsOfficePartnerRbacEntity givenSomeTemporaryPartnerBessler(final Integer partnerNumber) { return jpaAttempt.transacted(() -> { context.define("superuser-alex@hostsharing.net"); final var partnerRel = em.merge(givenSomeTemporaryPartnerRel("Erben Bessler", "fourth contact")); - final var newPartner = HsOfficePartnerEntity.builder() + final var newPartner = HsOfficePartnerRbacEntity.builder() .partnerRel(partnerRel) .partnerNumber(partnerNumber) .details(HsOfficePartnerDetailsEntity.builder() @@ -561,7 +561,7 @@ class HsOfficePartnerControllerAcceptanceTest extends ContextBasedTestWithCleanu @AfterEach void cleanup() { - cleanupAllNew(HsOfficePartnerEntity.class); + cleanupAllNew(HsOfficePartnerRbacEntity.class); // TODO: should not be necessary anymore, once it's deleted via after delete trigger cleanupAllNew(HsOfficeRelationRealEntity.class); diff --git a/src/test/java/net/hostsharing/hsadminng/hs/office/partner/HsOfficePartnerControllerRestTest.java b/src/test/java/net/hostsharing/hsadminng/hs/office/partner/HsOfficePartnerControllerRestTest.java index 13a81cdb..1ed5389b 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/office/partner/HsOfficePartnerControllerRestTest.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/office/partner/HsOfficePartnerControllerRestTest.java @@ -54,7 +54,7 @@ class HsOfficePartnerControllerRestTest { Context contextMock; @MockitoBean - HsOfficePartnerRepository partnerRepo; + HsOfficePartnerRbacRepository partnerRepo; @MockitoBean HsOfficeRelationRealRepository relationRepo; @@ -75,7 +75,7 @@ class HsOfficePartnerControllerRestTest { HsOfficeContactRbacEntity contactMock; @Mock - HsOfficePartnerEntity partnerMock; + HsOfficePartnerRbacEntity partnerMock; @BeforeEach void init() { @@ -174,7 +174,7 @@ class HsOfficePartnerControllerRestTest { @Test void respondWithPartner_ifPartnerNumberIsAvailable() throws Exception { // given - when(partnerRepo.findPartnerByPartnerNumber(12345)).thenReturn(Optional.of(HsOfficePartnerEntity.builder() + when(partnerRepo.findPartnerByPartnerNumber(12345)).thenReturn(Optional.of(HsOfficePartnerRbacEntity.builder() .partnerNumber(12345) .build())); diff --git a/src/test/java/net/hostsharing/hsadminng/hs/office/partner/HsOfficePartnerEntityPatcherUnitTest.java b/src/test/java/net/hostsharing/hsadminng/hs/office/partner/HsOfficePartnerEntityPatcherUnitTest.java index 102b54e5..b38c41ae 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/office/partner/HsOfficePartnerEntityPatcherUnitTest.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/office/partner/HsOfficePartnerEntityPatcherUnitTest.java @@ -24,7 +24,7 @@ import static org.mockito.Mockito.lenient; @ExtendWith(MockitoExtension.class) class HsOfficePartnerEntityPatcherUnitTest extends PatchUnitTestBase< HsOfficePartnerPatchResource, - HsOfficePartnerEntity + HsOfficePartnerRbacEntity > { private static final UUID INITIAL_PARTNER_UUID = UUID.randomUUID(); @@ -53,8 +53,8 @@ class HsOfficePartnerEntityPatcherUnitTest extends PatchUnitTestBase< } @Override - protected HsOfficePartnerEntity newInitialEntity() { - final var entity = HsOfficePartnerEntity.builder() + protected HsOfficePartnerRbacEntity newInitialEntity() { + final var entity = HsOfficePartnerRbacEntity.builder() .uuid(INITIAL_PARTNER_UUID) .partnerNumber(12345) .partnerRel(HsOfficeRelationRealEntity.builder() @@ -72,7 +72,7 @@ class HsOfficePartnerEntityPatcherUnitTest extends PatchUnitTestBase< } @Override - protected HsOfficePartnerEntityPatcher createPatcher(final HsOfficePartnerEntity partner) { + protected HsOfficePartnerEntityPatcher createPatcher(final HsOfficePartnerRbacEntity partner) { return new HsOfficePartnerEntityPatcher(em, partner); } @@ -83,7 +83,7 @@ class HsOfficePartnerEntityPatcherUnitTest extends PatchUnitTestBase< "partnerRel", HsOfficePartnerPatchResource::setPartnerRelUuid, PATCHED_PARTNER_ROLE_UUID, - HsOfficePartnerEntity::setPartnerRel, + HsOfficePartnerRbacEntity::setPartnerRel, newPartnerRel(PATCHED_PARTNER_ROLE_UUID)) .notNullable() ); diff --git a/src/test/java/net/hostsharing/hsadminng/hs/office/partner/HsOfficePartnerEntityUnitTest.java b/src/test/java/net/hostsharing/hsadminng/hs/office/partner/HsOfficePartnerEntityUnitTest.java index 93ca0315..79c24ec7 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/office/partner/HsOfficePartnerEntityUnitTest.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/office/partner/HsOfficePartnerEntityUnitTest.java @@ -12,7 +12,7 @@ import static org.assertj.core.api.Assertions.assertThat; class HsOfficePartnerEntityUnitTest { - private final HsOfficePartnerEntity givenPartner = HsOfficePartnerEntity.builder() + private final HsOfficePartnerRbacEntity givenPartner = HsOfficePartnerRbacEntity.builder() .partnerNumber(12345) .partnerRel(HsOfficeRelationRealEntity.builder() .anchor(HsOfficePersonRealEntity.builder() @@ -42,7 +42,7 @@ class HsOfficePartnerEntityUnitTest { @Test void definesRbac() { - final var rbacFlowchart = new RbacViewMermaidFlowchartGenerator(HsOfficePartnerEntity.rbac()).toString(); + final var rbacFlowchart = new RbacViewMermaidFlowchartGenerator(HsOfficePartnerRbacEntity.rbac()).toString(); assertThat(rbacFlowchart).isEqualTo(""" %%{init:{'flowchart':{'htmlLabels':false}}}%% flowchart TB 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 b625bfb9..07f5e810 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 @@ -41,7 +41,7 @@ import static org.assertj.core.api.Assertions.assertThat; class HsOfficePartnerRepositoryIntegrationTest extends ContextBasedTestWithCleanup { @Autowired - HsOfficePartnerRepository partnerRepo; + HsOfficePartnerRbacRepository partnerRepo; @Autowired HsOfficeRelationRealRepository relationRepo; @@ -82,7 +82,7 @@ class HsOfficePartnerRepositoryIntegrationTest extends ContextBasedTestWithClean // when final var result = attempt(em, () -> { - final var newPartner = HsOfficePartnerEntity.builder() + final var newPartner = HsOfficePartnerRbacEntity.builder() .partnerNumber(20031) .partnerRel(partnerRel) .details(HsOfficePartnerDetailsEntity.builder().build()) @@ -92,7 +92,7 @@ class HsOfficePartnerRepositoryIntegrationTest extends ContextBasedTestWithClean // then result.assertSuccessful(); - assertThat(result.returnedValue()).isNotNull().extracting(HsOfficePartnerEntity::getUuid).isNotNull(); + assertThat(result.returnedValue()).isNotNull().extracting(HsOfficePartnerRbacEntity::getUuid).isNotNull(); assertThatPartnerIsPersisted(result.returnedValue()); assertThat(partnerRepo.count()).isEqualTo(count + 1); } @@ -122,7 +122,7 @@ class HsOfficePartnerRepositoryIntegrationTest extends ContextBasedTestWithClean .build(); relationRepo.save(newRelation); - final var newPartner = HsOfficePartnerEntity.builder() + final var newPartner = HsOfficePartnerRbacEntity.builder() .partnerNumber(20032) .partnerRel(newRelation) .details(HsOfficePartnerDetailsEntity.builder().build()) @@ -180,7 +180,7 @@ class HsOfficePartnerRepositoryIntegrationTest extends ContextBasedTestWithClean null))); } - private void assertThatPartnerIsPersisted(final HsOfficePartnerEntity saved) { + private void assertThatPartnerIsPersisted(final HsOfficePartnerRbacEntity saved) { final var found = partnerRepo.findByUuid(saved.getUuid()); assertThat(found).isNotEmpty().get().extracting(Object::toString).isEqualTo(saved.toString()); } @@ -325,13 +325,13 @@ class HsOfficePartnerRepositoryIntegrationTest extends ContextBasedTestWithClean result.assertSuccessful(); } - private void assertThatPartnerActuallyInDatabase(final HsOfficePartnerEntity saved) { + private void assertThatPartnerActuallyInDatabase(final HsOfficePartnerRbacEntity saved) { final var found = partnerRepo.findByUuid(saved.getUuid()); - assertThat(found).isNotEmpty().get().isNotSameAs(saved).extracting(HsOfficePartnerEntity::toString).isEqualTo(saved.toString()); + assertThat(found).isNotEmpty().get().isNotSameAs(saved).extracting(HsOfficePartnerRbacEntity::toString).isEqualTo(saved.toString()); } private void assertThatPartnerIsVisibleForUserWithRole( - final HsOfficePartnerEntity entity, + final HsOfficePartnerRbacEntity entity, final String assumedRoles) { jpaAttempt.transacted(() -> { context("superuser-alex@hostsharing.net", assumedRoles); @@ -340,7 +340,7 @@ class HsOfficePartnerRepositoryIntegrationTest extends ContextBasedTestWithClean } private void assertThatPartnerIsNotVisibleForUserWithRole( - final HsOfficePartnerEntity entity, + final HsOfficePartnerRbacEntity entity, final String assumedRoles) { jpaAttempt.transacted(() -> { context("superuser-alex@hostsharing.net", assumedRoles); @@ -442,13 +442,13 @@ class HsOfficePartnerRepositoryIntegrationTest extends ContextBasedTestWithClean "[creating partner test-data , hs_office.partner, INSERT, 10010]"); } - private HsOfficePartnerEntity givenSomeTemporaryHostsharingPartner( + private HsOfficePartnerRbacEntity givenSomeTemporaryHostsharingPartner( final Integer partnerNumber, final String person, final String contact) { return jpaAttempt.transacted(() -> { context("superuser-alex@hostsharing.net"); final var partnerRel = givenSomeTemporaryHostsharingPartnerRel(person, contact); - final var newPartner = HsOfficePartnerEntity.builder() + final var newPartner = HsOfficePartnerRbacEntity.builder() .partnerNumber(partnerNumber) .partnerRel(partnerRel) .details(HsOfficePartnerDetailsEntity.builder().build()) @@ -476,21 +476,21 @@ class HsOfficePartnerRepositoryIntegrationTest extends ContextBasedTestWithClean return partnerRel; } - void exactlyThesePartnersAreReturned(final List actualResult, final String... partnerNames) { + void exactlyThesePartnersAreReturned(final List actualResult, final String... partnerNames) { assertThat(actualResult) - .extracting(HsOfficePartnerEntity::toString) + .extracting(HsOfficePartnerRbacEntity::toString) .containsExactlyInAnyOrder(partnerNames); } - void allThesePartnersAreReturned(final List actualResult, final String... partnerNames) { + void allThesePartnersAreReturned(final List actualResult, final String... partnerNames) { assertThat(actualResult) - .extracting(HsOfficePartnerEntity::toString) + .extracting(HsOfficePartnerRbacEntity::toString) .contains(partnerNames); } @AfterEach void cleanup() { - cleanupAllNew(HsOfficePartnerEntity.class); + cleanupAllNew(HsOfficePartnerRbacEntity.class); } private String[] distinct(final String[] strings) { 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 02358e28..560ab443 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 @@ -9,10 +9,10 @@ import static net.hostsharing.hsadminng.hs.office.person.HsOfficePersonType.LEGA public class TestHsOfficePartner { - public static final HsOfficePartnerEntity TEST_PARTNER = hsOfficePartnerWithLegalPerson("Test Ltd."); + public static final HsOfficePartnerRbacEntity TEST_PARTNER = hsOfficePartnerWithLegalPerson("Test Ltd."); - static public HsOfficePartnerEntity hsOfficePartnerWithLegalPerson(final String tradeName) { - return HsOfficePartnerEntity.builder() + static public HsOfficePartnerRbacEntity hsOfficePartnerWithLegalPerson(final String tradeName) { + return HsOfficePartnerRbacEntity.builder() .partnerNumber(10001) .partnerRel( HsOfficeRelationRealEntity.builder() -- 2.39.5 From 1dda477ec8ae84f0a7970d7d9274136460efbb2b Mon Sep 17 00:00:00 2001 From: Michael Hoennig Date: Tue, 14 Jan 2025 15:46:48 +0100 Subject: [PATCH 20/35] rename HsOfficePartnerEntity to HsOfficePartnerRbacEntity --- ...t.java => HsOfficePartnerRbacRepositoryIntegrationTest.java} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename src/test/java/net/hostsharing/hsadminng/hs/office/partner/{HsOfficePartnerRepositoryIntegrationTest.java => HsOfficePartnerRbacRepositoryIntegrationTest.java} (99%) diff --git a/src/test/java/net/hostsharing/hsadminng/hs/office/partner/HsOfficePartnerRepositoryIntegrationTest.java b/src/test/java/net/hostsharing/hsadminng/hs/office/partner/HsOfficePartnerRbacRepositoryIntegrationTest.java similarity index 99% rename from src/test/java/net/hostsharing/hsadminng/hs/office/partner/HsOfficePartnerRepositoryIntegrationTest.java rename to src/test/java/net/hostsharing/hsadminng/hs/office/partner/HsOfficePartnerRbacRepositoryIntegrationTest.java index 07f5e810..d6591322 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/office/partner/HsOfficePartnerRepositoryIntegrationTest.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/office/partner/HsOfficePartnerRbacRepositoryIntegrationTest.java @@ -38,7 +38,7 @@ import static org.assertj.core.api.Assertions.assertThat; @DataJpaTest @Import( { Context.class, JpaAttempt.class }) -class HsOfficePartnerRepositoryIntegrationTest extends ContextBasedTestWithCleanup { +class HsOfficePartnerRbacRepositoryIntegrationTest extends ContextBasedTestWithCleanup { @Autowired HsOfficePartnerRbacRepository partnerRepo; -- 2.39.5 From f3360d36bfe44549cf65aea8583763e691cad52a Mon Sep 17 00:00:00 2001 From: Michael Hoennig Date: Tue, 14 Jan 2025 16:56:08 +0100 Subject: [PATCH 21/35] split HsOfficePartnerRbacEntity into HsOfficePartner, HsOfficePartnerRbacEntity and HsOfficePartnerRealEntity --- .../office/debitor/HsOfficeDebitorEntity.java | 7 +- .../HsOfficeMembershipController.java | 4 +- .../membership/HsOfficeMembershipEntity.java | 4 +- .../hs/office/partner/HsOfficePartner.java | 103 ++++++++++++++++++ .../partner/HsOfficePartnerRbacEntity.java | 79 +------------- .../HsOfficePartnerRbacRepository.java | 14 +-- .../partner/HsOfficePartnerRealEntity.java | 21 ++++ .../HsOfficePartnerRealRepository.java | 41 +++++++ .../hs/migration/BaseOfficeDataImport.java | 6 +- ...opAssetsTransactionControllerRestTest.java | 6 +- .../HsOfficeDebitorEntityUnitTest.java | 12 +- ...fficeDebitorRepositoryIntegrationTest.java | 4 +- .../office/debitor/TestHsOfficeDebitor.java | 2 +- ...iceMembershipControllerAcceptanceTest.java | 4 +- .../HsOfficeMembershipControllerRestTest.java | 3 +- ...OfficeMembershipEntityPatcherUnitTest.java | 2 +- .../HsOfficeMembershipEntityUnitTest.java | 6 +- ...ceMembershipRepositoryIntegrationTest.java | 4 +- .../office/membership/TestHsMembership.java | 2 +- ...tner.java => HsOfficeTestRealPartner.java} | 8 +- 20 files changed, 214 insertions(+), 118 deletions(-) create mode 100644 src/main/java/net/hostsharing/hsadminng/hs/office/partner/HsOfficePartner.java create mode 100644 src/main/java/net/hostsharing/hsadminng/hs/office/partner/HsOfficePartnerRealEntity.java create mode 100644 src/main/java/net/hostsharing/hsadminng/hs/office/partner/HsOfficePartnerRealRepository.java rename src/test/java/net/hostsharing/hsadminng/hs/office/partner/{TestHsOfficePartner.java => HsOfficeTestRealPartner.java} (87%) 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 32d9038f..ecce6e74 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,7 +7,8 @@ import lombok.NoArgsConstructor; import lombok.Setter; import net.hostsharing.hsadminng.errors.DisplayAs; import net.hostsharing.hsadminng.hs.office.bankaccount.HsOfficeBankAccountEntity; -import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerRbacEntity; +import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartner; +import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerRealEntity; import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelation; import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationRealEntity; import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationRbacEntity; @@ -96,7 +97,7 @@ public class HsOfficeDebitorEntity implements BaseEntity, ) """) @NotFound(action = NotFoundAction.IGNORE) // TODO.impl: map a simplified raw-PartnerEntity, just for the partner-number - private HsOfficePartnerRbacEntity partner; + private HsOfficePartnerRealEntity partner; @Column(name = "debitornumbersuffix", length = 2) @Pattern(regexp = TWO_DECIMAL_DIGITS) @@ -145,7 +146,7 @@ public class HsOfficeDebitorEntity implements BaseEntity, public String getTaggedDebitorNumber() { return ofNullable(partner) .filter(partner -> debitorNumberSuffix != null) - .map(HsOfficePartnerRbacEntity::getPartnerNumber) + .map(HsOfficePartner::getPartnerNumber) .map(partnerNumber -> DEBITOR_NUMBER_TAG + partnerNumber + debitorNumberSuffix) .orElse(null); } 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 0d1b9110..61ce652b 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 @@ -7,7 +7,7 @@ import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeMember import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeMembershipPatchResource; import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeMembershipResource; import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerRbacEntity; -import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerRbacRepository; +import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerRealRepository; import net.hostsharing.hsadminng.mapper.StrictMapper; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.ResponseEntity; @@ -33,7 +33,7 @@ public class HsOfficeMembershipController implements HsOfficeMembershipsApi { private StrictMapper mapper; @Autowired - private HsOfficePartnerRbacRepository partnerRepo; + private HsOfficePartnerRealRepository partnerRepo; @Autowired private HsOfficeMembershipRepository membershipRepo; 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 08c7ae93..2d9c8248 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 @@ -8,9 +8,9 @@ import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; import net.hostsharing.hsadminng.errors.DisplayAs; +import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerRealEntity; import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationRbacEntity; import net.hostsharing.hsadminng.persistence.BaseEntity; -import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerRbacEntity; import net.hostsharing.hsadminng.rbac.generator.RbacSpec; import net.hostsharing.hsadminng.rbac.generator.RbacSpec.SQL; import net.hostsharing.hsadminng.rbac.role.WithRoleId; @@ -85,7 +85,7 @@ public class HsOfficeMembershipEntity implements BaseEntity> implements Stringifyable, BaseEntity { + + public static final String PARTNER_NUMBER_TAG = "P-"; + + protected static Stringify stringify = stringify(HsOfficePartner.class, "partner") + .withIdProp(HsOfficePartner::toShortString) + .withProp(p -> ofNullable(p.getPartnerRel()) + .map(HsOfficeRelation::getHolder) + .map(HsOfficePerson::toShortString) + .orElse(null)) + .withProp(p -> ofNullable(p.getPartnerRel()) + .map(HsOfficeRelation::getContact) + .map(HsOfficeContact::toShortString) + .orElse(null)) + .quotedValues(false); + + @Id + @GeneratedValue + private UUID uuid; + + @Version + private int version; + + @Column(name = "partnernumber", columnDefinition = "numeric(5) not null") + private Integer partnerNumber; + + @ManyToOne(cascade = { PERSIST, MERGE, REFRESH, DETACH }, optional = false, fetch = FetchType.LAZY) + @JoinColumn(name = "partnerreluuid", nullable = false) + private HsOfficeRelationRealEntity partnerRel; + + @ManyToOne(cascade = { PERSIST, MERGE, REFRESH, DETACH }, optional = true, fetch = FetchType.LAZY) + @JoinColumn(name = "detailsuuid") + @NotFound(action = NotFoundAction.IGNORE) + private HsOfficePartnerDetailsEntity details; + + @Override + public T load() { + BaseEntity.super.load(); + partnerRel.load(); + if (details != null) { + details.load(); + } + //noinspection unchecked + return (T) this; + } + + public String getTaggedPartnerNumber() { + return PARTNER_NUMBER_TAG + partnerNumber; + } + + @Override + public String toString() { + return stringify.apply(this); + } + + @Override + public String toShortString() { + return getTaggedPartnerNumber(); + } +} diff --git a/src/main/java/net/hostsharing/hsadminng/hs/office/partner/HsOfficePartnerRbacEntity.java b/src/main/java/net/hostsharing/hsadminng/hs/office/partner/HsOfficePartnerRbacEntity.java index 35f9c4c6..eddab1c7 100644 --- a/src/main/java/net/hostsharing/hsadminng/hs/office/partner/HsOfficePartnerRbacEntity.java +++ b/src/main/java/net/hostsharing/hsadminng/hs/office/partner/HsOfficePartnerRbacEntity.java @@ -1,27 +1,16 @@ package net.hostsharing.hsadminng.hs.office.partner; -import lombok.AllArgsConstructor; -import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; +import lombok.experimental.SuperBuilder; import net.hostsharing.hsadminng.errors.DisplayAs; -import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContact; -import net.hostsharing.hsadminng.hs.office.person.HsOfficePerson; -import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationRealEntity; import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationRbacEntity; -import net.hostsharing.hsadminng.persistence.BaseEntity; -import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelation; import net.hostsharing.hsadminng.rbac.generator.RbacSpec; import net.hostsharing.hsadminng.rbac.generator.RbacSpec.SQL; -import net.hostsharing.hsadminng.repr.Stringify; -import net.hostsharing.hsadminng.repr.Stringifyable; -import org.hibernate.annotations.NotFound; -import org.hibernate.annotations.NotFoundAction; import jakarta.persistence.*; import java.io.IOException; -import java.util.UUID; import static jakarta.persistence.CascadeType.*; import static net.hostsharing.hsadminng.rbac.generator.RbacSpec.Column.dependsOnColumn; @@ -32,75 +21,15 @@ import static net.hostsharing.hsadminng.rbac.generator.RbacSpec.Permission.SELEC import static net.hostsharing.hsadminng.rbac.generator.RbacSpec.Role.*; import static net.hostsharing.hsadminng.rbac.generator.RbacSpec.SQL.directlyFetchedByDependsOnColumn; import static net.hostsharing.hsadminng.rbac.generator.RbacSpec.rbacViewFor; -import static java.util.Optional.ofNullable; -import static net.hostsharing.hsadminng.repr.Stringify.stringify; @Entity @Table(schema = "hs_office", name = "partner_rv") @Getter @Setter -@Builder +@SuperBuilder(toBuilder = true) @NoArgsConstructor -@AllArgsConstructor -@DisplayAs("Partner") -public class HsOfficePartnerRbacEntity implements Stringifyable, BaseEntity { - - public static final String PARTNER_NUMBER_TAG = "P-"; - - private static Stringify stringify = stringify(HsOfficePartnerRbacEntity.class, "partner") - .withIdProp(HsOfficePartnerRbacEntity::toShortString) - .withProp(p -> ofNullable(p.getPartnerRel()) - .map(HsOfficeRelation::getHolder) - .map(HsOfficePerson::toShortString) - .orElse(null)) - .withProp(p -> ofNullable(p.getPartnerRel()) - .map(HsOfficeRelation::getContact) - .map(HsOfficeContact::toShortString) - .orElse(null)) - .quotedValues(false); - - @Id - @GeneratedValue - private UUID uuid; - - @Version - private int version; - - @Column(name = "partnernumber", columnDefinition = "numeric(5) not null") - private Integer partnerNumber; - - @ManyToOne(cascade = { PERSIST, MERGE, REFRESH, DETACH }, optional = false, fetch = FetchType.LAZY) - @JoinColumn(name = "partnerreluuid", nullable = false) - private HsOfficeRelationRealEntity partnerRel; - - @ManyToOne(cascade = { PERSIST, MERGE, REFRESH, DETACH }, optional = true, fetch = FetchType.LAZY) - @JoinColumn(name = "detailsuuid") - @NotFound(action = NotFoundAction.IGNORE) - private HsOfficePartnerDetailsEntity details; - - @Override - public HsOfficePartnerRbacEntity load() { - BaseEntity.super.load(); - partnerRel.load(); - if (details != null) { - details.load(); - } - return this; - } - - public String getTaggedPartnerNumber() { - return PARTNER_NUMBER_TAG + partnerNumber; - } - - @Override - public String toString() { - return stringify.apply(this); - } - - @Override - public String toShortString() { - return getTaggedPartnerNumber(); - } +@DisplayAs("RbacPartner") +public class HsOfficePartnerRbacEntity extends HsOfficePartner { public static RbacSpec rbac() { return rbacViewFor("partner", HsOfficePartnerRbacEntity.class) diff --git a/src/main/java/net/hostsharing/hsadminng/hs/office/partner/HsOfficePartnerRbacRepository.java b/src/main/java/net/hostsharing/hsadminng/hs/office/partner/HsOfficePartnerRbacRepository.java index f745c1da..759fd133 100644 --- a/src/main/java/net/hostsharing/hsadminng/hs/office/partner/HsOfficePartnerRbacRepository.java +++ b/src/main/java/net/hostsharing/hsadminng/hs/office/partner/HsOfficePartnerRbacRepository.java @@ -10,10 +10,10 @@ import java.util.UUID; public interface HsOfficePartnerRbacRepository extends Repository { - @Timed("app.office.partners.repo.findByUuid") + @Timed("app.office.partners.repo.findByUuid.rbac") Optional findByUuid(UUID id); - @Timed("app.office.partners.repo.findAll") + @Timed("app.office.partners.repo.findAll.rbac") List findAll(); // TODO.refa: move to a repo in test sources @Query(value = """ @@ -30,18 +30,18 @@ public interface HsOfficePartnerRbacRepository extends Repository findPartnerByOptionalNameLike(String name); - @Timed("app.office.partners.repo.findPartnerByPartnerNumber") + @Timed("app.office.partners.repo.findPartnerByPartnerNumber.rbac") Optional findPartnerByPartnerNumber(Integer partnerNumber); - @Timed("app.office.partners.repo.save") + @Timed("app.office.partners.repo.save.rbac") HsOfficePartnerRbacEntity save(final HsOfficePartnerRbacEntity entity); - @Timed("app.office.partners.repo.count") + @Timed("app.office.partners.repo.count.rbac") long count(); - @Timed("app.office.partners.repo.deleteByUuid") + @Timed("app.office.partners.repo.deleteByUuid.rbac") int deleteByUuid(UUID uuid); } diff --git a/src/main/java/net/hostsharing/hsadminng/hs/office/partner/HsOfficePartnerRealEntity.java b/src/main/java/net/hostsharing/hsadminng/hs/office/partner/HsOfficePartnerRealEntity.java new file mode 100644 index 00000000..ddaf346b --- /dev/null +++ b/src/main/java/net/hostsharing/hsadminng/hs/office/partner/HsOfficePartnerRealEntity.java @@ -0,0 +1,21 @@ +package net.hostsharing.hsadminng.hs.office.partner; + +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import lombok.experimental.SuperBuilder; +import net.hostsharing.hsadminng.errors.DisplayAs; + +import jakarta.persistence.Entity; +import jakarta.persistence.Table; + + +@Entity +@Table(schema = "hs_office", name = "partner") +@Getter +@Setter +@SuperBuilder(toBuilder = true) +@NoArgsConstructor +@DisplayAs("RealPartner") +public class HsOfficePartnerRealEntity extends HsOfficePartner { +} diff --git a/src/main/java/net/hostsharing/hsadminng/hs/office/partner/HsOfficePartnerRealRepository.java b/src/main/java/net/hostsharing/hsadminng/hs/office/partner/HsOfficePartnerRealRepository.java new file mode 100644 index 00000000..a971cbf2 --- /dev/null +++ b/src/main/java/net/hostsharing/hsadminng/hs/office/partner/HsOfficePartnerRealRepository.java @@ -0,0 +1,41 @@ +package net.hostsharing.hsadminng.hs.office.partner; + +import io.micrometer.core.annotation.Timed; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.Repository; + +import java.util.List; +import java.util.Optional; +import java.util.UUID; + +public interface HsOfficePartnerRealRepository extends Repository { + + @Timed("app.office.partners.repo.findByUuid.real") + Optional findByUuid(UUID id); + + @Timed("app.office.partners.repo.findAll.real") + List findAll(); // TODO.refa: move to a repo in test sources + + @Query(value = """ + select partner.uuid, partner.detailsuuid, partner.partnernumber, partner.partnerreluuid, partner.version + from hs_office.partner partner + join hs_office.relation partnerRel on partnerRel.uuid = partner.partnerreluuid + join hs_office.contact contact on contact.uuid = partnerRel.contactuuid + join hs_office.person partnerPerson on partnerPerson.uuid = partnerRel.holderuuid + left join hs_office.partner_details_rv partnerDetails on partnerDetails.uuid = partner.detailsuuid + where :name is null + or (partnerDetails.uuid is not null and partnerDetails.birthname like (cast(:name as text) || '%') escape '') + or contact.caption like (cast(:name as text) || '%') escape '' + or partnerPerson.tradename like (cast(:name as text) || '%') escape '' + or partnerPerson.givenname like (cast(:name as text) || '%') escape '' + or partnerPerson.familyname like (cast(:name as text) || '%') escape '' + """, nativeQuery = true) + @Timed("app.office.partners.repo.findPartnerByOptionalNameLike.real") + List findPartnerByOptionalNameLike(String name); + + @Timed("app.office.partners.repo.findPartnerByPartnerNumber.real") + Optional findPartnerByPartnerNumber(Integer partnerNumber); + + @Timed("app.office.partners.repo.save.real") + HsOfficePartnerRealEntity save(final HsOfficePartnerRealEntity entity); +} diff --git a/src/test/java/net/hostsharing/hsadminng/hs/migration/BaseOfficeDataImport.java b/src/test/java/net/hostsharing/hsadminng/hs/migration/BaseOfficeDataImport.java index 35547e1d..f4095e5b 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/migration/BaseOfficeDataImport.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/migration/BaseOfficeDataImport.java @@ -10,7 +10,7 @@ import net.hostsharing.hsadminng.hs.office.debitor.HsOfficeDebitorEntity; import net.hostsharing.hsadminng.hs.office.membership.HsOfficeMembershipEntity; import net.hostsharing.hsadminng.hs.office.membership.HsOfficeMembershipStatus; import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerDetailsEntity; -import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerRbacEntity; +import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerRealEntity; import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonRealEntity; import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonType; import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelation; @@ -84,7 +84,7 @@ public abstract class BaseOfficeDataImport extends CsvDataImport { static Map contacts = new WriteOnceMap<>(); static Map persons = new WriteOnceMap<>(); - static Map partners = new WriteOnceMap<>(); + static Map partners = new WriteOnceMap<>(); static Map debitors = new WriteOnceMap<>(); static Map memberships = new WriteOnceMap<>(); @@ -743,7 +743,7 @@ public abstract class BaseOfficeDataImport extends CsvDataImport { null // is set during contacts import depending on assigned roles ); - final var partner = HsOfficePartnerRbacEntity.builder() + final var partner = HsOfficePartnerRealEntity.builder() .partnerNumber(rec.getInteger("member_id")) .details(HsOfficePartnerDetailsEntity.builder().build()) .partnerRel(partnerRel) diff --git a/src/test/java/net/hostsharing/hsadminng/hs/office/coopassets/HsOfficeCoopAssetsTransactionControllerRestTest.java b/src/test/java/net/hostsharing/hsadminng/hs/office/coopassets/HsOfficeCoopAssetsTransactionControllerRestTest.java index 1e2cfa63..45b2e30d 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/office/coopassets/HsOfficeCoopAssetsTransactionControllerRestTest.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/office/coopassets/HsOfficeCoopAssetsTransactionControllerRestTest.java @@ -4,7 +4,7 @@ import net.hostsharing.hsadminng.config.JsonObjectMapperConfiguration; import net.hostsharing.hsadminng.context.Context; import net.hostsharing.hsadminng.hs.office.membership.HsOfficeMembershipEntity; import net.hostsharing.hsadminng.hs.office.membership.HsOfficeMembershipRepository; -import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerRbacEntity; +import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerRealEntity; import net.hostsharing.hsadminng.mapper.StrictMapper; import net.hostsharing.hsadminng.persistence.EntityManagerWrapper; import net.hostsharing.hsadminng.rbac.test.JsonBuilder; @@ -67,7 +67,7 @@ class HsOfficeCoopAssetsTransactionControllerRestTest { private static final String ORIGIN_MEMBER_NUMBER = "M-1111100"; public final HsOfficeMembershipEntity ORIGIN_TARGET_MEMBER_ENTITY = HsOfficeMembershipEntity.builder() .uuid(ORIGIN_MEMBERSHIP_UUID) - .partner(HsOfficePartnerRbacEntity.builder() + .partner(HsOfficePartnerRealEntity.builder() .partnerNumber(partnerNumberOf(ORIGIN_MEMBER_NUMBER)) .build()) .memberNumberSuffix(suffixOf(ORIGIN_MEMBER_NUMBER)) @@ -77,7 +77,7 @@ class HsOfficeCoopAssetsTransactionControllerRestTest { private static final String AVAILABLE_TARGET_MEMBER_NUMBER = "M-1234500"; public final HsOfficeMembershipEntity AVAILABLE_MEMBER_ENTITY = HsOfficeMembershipEntity.builder() .uuid(AVAILABLE_TARGET_MEMBERSHIP_UUID) - .partner(HsOfficePartnerRbacEntity.builder() + .partner(HsOfficePartnerRealEntity.builder() .partnerNumber(partnerNumberOf(AVAILABLE_TARGET_MEMBER_NUMBER)) .build()) .memberNumberSuffix(suffixOf(AVAILABLE_TARGET_MEMBER_NUMBER)) diff --git a/src/test/java/net/hostsharing/hsadminng/hs/office/debitor/HsOfficeDebitorEntityUnitTest.java b/src/test/java/net/hostsharing/hsadminng/hs/office/debitor/HsOfficeDebitorEntityUnitTest.java index 023fcc6b..468e7006 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/office/debitor/HsOfficeDebitorEntityUnitTest.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/office/debitor/HsOfficeDebitorEntityUnitTest.java @@ -1,7 +1,7 @@ package net.hostsharing.hsadminng.hs.office.debitor; import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactRealEntity; -import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerRbacEntity; +import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerRealEntity; import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonRealEntity; import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonType; import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationRealEntity; @@ -30,7 +30,7 @@ class HsOfficeDebitorEntityUnitTest { .debitorNumberSuffix("67") .debitorRel(givenDebitorRel) .defaultPrefix("som") - .partner(HsOfficePartnerRbacEntity.builder() + .partner(HsOfficePartnerRealEntity.builder() .partnerNumber(12345) .build()) .build(); @@ -45,7 +45,7 @@ class HsOfficeDebitorEntityUnitTest { final var given = HsOfficeDebitorEntity.builder() .debitorRel(givenDebitorRel) .debitorNumberSuffix("67") - .partner(HsOfficePartnerRbacEntity.builder() + .partner(HsOfficePartnerRealEntity.builder() .partnerNumber(12345) .build()) .build(); @@ -60,7 +60,7 @@ class HsOfficeDebitorEntityUnitTest { final var given = HsOfficeDebitorEntity.builder() .debitorRel(givenDebitorRel) .debitorNumberSuffix("67") - .partner(HsOfficePartnerRbacEntity.builder() + .partner(HsOfficePartnerRealEntity.builder() .partnerNumber(12345) .build()) .build(); @@ -88,7 +88,7 @@ class HsOfficeDebitorEntityUnitTest { final var given = HsOfficeDebitorEntity.builder() .debitorRel(givenDebitorRel) .debitorNumberSuffix("67") - .partner(HsOfficePartnerRbacEntity.builder().build()) + .partner(HsOfficePartnerRealEntity.builder().build()) .build(); final var result = given.getTaggedDebitorNumber(); @@ -101,7 +101,7 @@ class HsOfficeDebitorEntityUnitTest { final var given = HsOfficeDebitorEntity.builder() .debitorRel(givenDebitorRel) .debitorNumberSuffix(null) - .partner(HsOfficePartnerRbacEntity.builder() + .partner(HsOfficePartnerRealEntity.builder() .partnerNumber(12345) .build()) .build(); 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 c3537f74..7989cf74 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 @@ -3,7 +3,7 @@ package net.hostsharing.hsadminng.hs.office.debitor; import net.hostsharing.hsadminng.context.Context; import net.hostsharing.hsadminng.hs.office.bankaccount.HsOfficeBankAccountRepository; import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactRealRepository; -import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerRbacRepository; +import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerRealRepository; import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonRealRepository; import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelation; import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationRealEntity; @@ -48,7 +48,7 @@ class HsOfficeDebitorRepositoryIntegrationTest extends ContextBasedTestWithClean HsOfficeDebitorRepository debitorRepo; @Autowired - HsOfficePartnerRbacRepository partnerRepo; + HsOfficePartnerRealRepository partnerRepo; @Autowired HsOfficeContactRealRepository contactRealRepo; 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 cd6233dc..a0dcb83d 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 @@ -5,7 +5,7 @@ import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonRealEntity; import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationRealEntity; import static net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactRealTestEntity.TEST_REAL_CONTACT; -import static net.hostsharing.hsadminng.hs.office.partner.TestHsOfficePartner.TEST_PARTNER; +import static net.hostsharing.hsadminng.hs.office.partner.HsOfficeTestRealPartner.TEST_PARTNER; @UtilityClass public class TestHsOfficeDebitor { diff --git a/src/test/java/net/hostsharing/hsadminng/hs/office/membership/HsOfficeMembershipControllerAcceptanceTest.java b/src/test/java/net/hostsharing/hsadminng/hs/office/membership/HsOfficeMembershipControllerAcceptanceTest.java index ed7a8925..a2306ba8 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/office/membership/HsOfficeMembershipControllerAcceptanceTest.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/office/membership/HsOfficeMembershipControllerAcceptanceTest.java @@ -5,7 +5,7 @@ import io.restassured.RestAssured; import io.restassured.http.ContentType; import net.hostsharing.hsadminng.HsadminNgApplication; import net.hostsharing.hsadminng.context.Context; -import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerRbacRepository; +import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerRealRepository; import net.hostsharing.hsadminng.rbac.test.ContextBasedTestWithCleanup; import net.hostsharing.hsadminng.rbac.test.JpaAttempt; import net.hostsharing.hsadminng.config.DisableSecurityConfig; @@ -54,7 +54,7 @@ class HsOfficeMembershipControllerAcceptanceTest extends ContextBasedTestWithCle HsOfficeMembershipRepository membershipRepo; @Autowired - HsOfficePartnerRbacRepository partnerRepo; + HsOfficePartnerRealRepository partnerRepo; @Autowired JpaAttempt jpaAttempt; 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 54ffbd85..eda9a0c8 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 @@ -4,6 +4,7 @@ import net.hostsharing.hsadminng.context.Context; import net.hostsharing.hsadminng.hs.office.coopassets.HsOfficeCoopAssetsTransactionRepository; import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerRbacEntity; import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerRbacRepository; +import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerRealEntity; import net.hostsharing.hsadminng.mapper.StrictMapper; import net.hostsharing.hsadminng.persistence.EntityManagerWrapper; import net.hostsharing.hsadminng.config.DisableSecurityConfig; @@ -39,7 +40,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. @ActiveProfiles("test") public class HsOfficeMembershipControllerRestTest { - private static final HsOfficePartnerRbacEntity PARTNER_12345 = HsOfficePartnerRbacEntity.builder() + private static final HsOfficePartnerRealEntity PARTNER_12345 = HsOfficePartnerRealEntity.builder() .partnerNumber(12345) .build(); public static final HsOfficeMembershipEntity MEMBERSHIP_1234501 = HsOfficeMembershipEntity.builder() diff --git a/src/test/java/net/hostsharing/hsadminng/hs/office/membership/HsOfficeMembershipEntityPatcherUnitTest.java b/src/test/java/net/hostsharing/hsadminng/hs/office/membership/HsOfficeMembershipEntityPatcherUnitTest.java index e5ffccfe..f631e24a 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/office/membership/HsOfficeMembershipEntityPatcherUnitTest.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/office/membership/HsOfficeMembershipEntityPatcherUnitTest.java @@ -17,7 +17,7 @@ import java.time.LocalDate; import java.util.UUID; import java.util.stream.Stream; -import static net.hostsharing.hsadminng.hs.office.partner.TestHsOfficePartner.TEST_PARTNER; +import static net.hostsharing.hsadminng.hs.office.partner.HsOfficeTestRealPartner.TEST_PARTNER; import static org.junit.jupiter.api.TestInstance.Lifecycle.PER_CLASS; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; diff --git a/src/test/java/net/hostsharing/hsadminng/hs/office/membership/HsOfficeMembershipEntityUnitTest.java b/src/test/java/net/hostsharing/hsadminng/hs/office/membership/HsOfficeMembershipEntityUnitTest.java index 49219290..975ca8d0 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/office/membership/HsOfficeMembershipEntityUnitTest.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/office/membership/HsOfficeMembershipEntityUnitTest.java @@ -1,7 +1,7 @@ package net.hostsharing.hsadminng.hs.office.membership; import io.hypersistence.utils.hibernate.type.range.Range; -import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerRbacEntity; +import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerRealEntity; import net.hostsharing.hsadminng.rbac.generator.RbacViewMermaidFlowchartGenerator; import org.junit.jupiter.api.Test; @@ -10,7 +10,7 @@ import java.lang.reflect.InvocationTargetException; import java.time.LocalDate; import java.util.Arrays; -import static net.hostsharing.hsadminng.hs.office.partner.TestHsOfficePartner.TEST_PARTNER; +import static net.hostsharing.hsadminng.hs.office.partner.HsOfficeTestRealPartner.TEST_PARTNER; import static org.assertj.core.api.Assertions.assertThat; class HsOfficeMembershipEntityUnitTest { @@ -57,7 +57,7 @@ class HsOfficeMembershipEntityUnitTest { @Test void getMemberNumberWithoutPartnerNumberButWithSuffix() { - givenMembership.setPartner(HsOfficePartnerRbacEntity.builder().build()); + givenMembership.setPartner(HsOfficePartnerRealEntity.builder().build()); final var result = givenMembership.getMemberNumber(); assertThat(result).isEqualTo(null); } 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 04be5edd..44713c61 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 @@ -3,7 +3,7 @@ package net.hostsharing.hsadminng.hs.office.membership; import io.hypersistence.utils.hibernate.type.range.Range; import net.hostsharing.hsadminng.context.Context; import net.hostsharing.hsadminng.hs.office.debitor.HsOfficeDebitorRepository; -import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerRbacRepository; +import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerRealRepository; import net.hostsharing.hsadminng.rbac.test.ContextBasedTestWithCleanup; import net.hostsharing.hsadminng.rbac.grant.RawRbacGrantRepository; import net.hostsharing.hsadminng.rbac.role.RawRbacRoleRepository; @@ -37,7 +37,7 @@ class HsOfficeMembershipRepositoryIntegrationTest extends ContextBasedTestWithCl HsOfficeMembershipRepository membershipRepo; @Autowired - HsOfficePartnerRbacRepository partnerRepo; + HsOfficePartnerRealRepository partnerRepo; @Autowired HsOfficeDebitorRepository debitorRepo; 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 857e9369..416a29ff 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 @@ -4,7 +4,7 @@ import io.hypersistence.utils.hibernate.type.range.Range; import java.time.LocalDate; -import static net.hostsharing.hsadminng.hs.office.partner.TestHsOfficePartner.TEST_PARTNER; +import static net.hostsharing.hsadminng.hs.office.partner.HsOfficeTestRealPartner.TEST_PARTNER; public class TestHsMembership { diff --git a/src/test/java/net/hostsharing/hsadminng/hs/office/partner/TestHsOfficePartner.java b/src/test/java/net/hostsharing/hsadminng/hs/office/partner/HsOfficeTestRealPartner.java similarity index 87% rename from src/test/java/net/hostsharing/hsadminng/hs/office/partner/TestHsOfficePartner.java rename to src/test/java/net/hostsharing/hsadminng/hs/office/partner/HsOfficeTestRealPartner.java index 560ab443..630a1782 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/office/partner/TestHsOfficePartner.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/office/partner/HsOfficeTestRealPartner.java @@ -7,12 +7,12 @@ import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationType; import static net.hostsharing.hsadminng.hs.office.person.HsOfficePersonType.LEGAL_PERSON; -public class TestHsOfficePartner { +public class HsOfficeTestRealPartner { - public static final HsOfficePartnerRbacEntity TEST_PARTNER = hsOfficePartnerWithLegalPerson("Test Ltd."); + public static final HsOfficePartnerRealEntity TEST_PARTNER = hsOfficePartnerWithLegalPerson("Test Ltd."); - static public HsOfficePartnerRbacEntity hsOfficePartnerWithLegalPerson(final String tradeName) { - return HsOfficePartnerRbacEntity.builder() + static public HsOfficePartnerRealEntity hsOfficePartnerWithLegalPerson(final String tradeName) { + return HsOfficePartnerRealEntity.builder() .partnerNumber(10001) .partnerRel( HsOfficeRelationRealEntity.builder() -- 2.39.5 From 70b12bba589d182d1f32d92a53c81372cbb42e00 Mon Sep 17 00:00:00 2001 From: Michael Hoennig Date: Tue, 14 Jan 2025 17:06:02 +0100 Subject: [PATCH 22/35] make HsOfficeDebitorEntity.partner mandatory --- .../hsadminng/hs/office/debitor/HsOfficeDebitorEntity.java | 4 +--- .../hs/office/debitor/HsOfficeDebitorRepository.java | 4 ++-- 2 files changed, 3 insertions(+), 5 deletions(-) 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 ecce6e74..8fc5c0f6 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 @@ -17,7 +17,6 @@ import net.hostsharing.hsadminng.rbac.generator.RbacSpec; import net.hostsharing.hsadminng.rbac.generator.RbacSpec.SQL; import net.hostsharing.hsadminng.repr.Stringify; import net.hostsharing.hsadminng.repr.Stringifyable; -import org.hibernate.annotations.GenericGenerator; import org.hibernate.annotations.JoinFormula; import org.hibernate.annotations.NotFound; import org.hibernate.annotations.NotFoundAction; @@ -76,7 +75,6 @@ public class HsOfficeDebitorEntity implements BaseEntity, @Id @GeneratedValue - @GenericGenerator(name = "UUID", strategy = "org.hibernate.id.UUIDGenerator") private UUID uuid; @Version @@ -96,7 +94,7 @@ public class HsOfficeDebitorEntity implements BaseEntity, WHERE pRel.holderUuid = dRel.anchorUuid ) """) - @NotFound(action = NotFoundAction.IGNORE) // TODO.impl: map a simplified raw-PartnerEntity, just for the partner-number + @NotFound(action = NotFoundAction.EXCEPTION) // TODO.impl: map a simplified raw-PartnerEntity, just for the partner-number private HsOfficePartnerRealEntity partner; @Column(name = "debitornumbersuffix", length = 2) diff --git a/src/main/java/net/hostsharing/hsadminng/hs/office/debitor/HsOfficeDebitorRepository.java b/src/main/java/net/hostsharing/hsadminng/hs/office/debitor/HsOfficeDebitorRepository.java index fa02053b..588f7a00 100644 --- a/src/main/java/net/hostsharing/hsadminng/hs/office/debitor/HsOfficeDebitorRepository.java +++ b/src/main/java/net/hostsharing/hsadminng/hs/office/debitor/HsOfficeDebitorRepository.java @@ -19,7 +19,7 @@ public interface HsOfficeDebitorRepository extends Repository Date: Tue, 14 Jan 2025 17:12:01 +0100 Subject: [PATCH 23/35] remove gate for debitor.partner == null - should not happen anymore --- .../hs/office/debitor/HsOfficeDebitorController.java | 4 +--- .../hsadminng/hs/office/debitor/HsOfficeDebitorEntity.java | 4 +--- 2 files changed, 2 insertions(+), 6 deletions(-) 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 78b8082d..6b7dc93e 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 @@ -222,8 +222,6 @@ public class HsOfficeDebitorController implements HsOfficeDebitorsApi { final BiConsumer ENTITY_TO_RESOURCE_POSTMAPPER = (entity, resource) -> { resource.setDebitorNumber(entity.getTaggedDebitorNumber()); - if (resource.getPartner() != null) { // FIXME: should not happen - resource.getPartner().setPartnerNumber(entity.getPartner().getTaggedPartnerNumber()); - } + resource.getPartner().setPartnerNumber(entity.getPartner().getTaggedPartnerNumber()); }; } 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 8fc5c0f6..4e20fbf8 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 @@ -131,9 +131,7 @@ public class HsOfficeDebitorEntity implements BaseEntity, @Override public HsOfficeDebitorEntity load() { BaseEntity.super.load(); - if (partner != null) { // FIXME: should not happen - partner.load(); - } + partner.load(); debitorRel.load(); if (refundBankAccount != null) { refundBankAccount.load(); -- 2.39.5 From c2c1237d4e6ef1e8ec0d471a51f534352b20d375 Mon Sep 17 00:00:00 2001 From: Michael Hoennig Date: Tue, 14 Jan 2025 17:12:30 +0100 Subject: [PATCH 24/35] cleanup --- .../partner/HsOfficePartnerRbacRepositoryIntegrationTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/net/hostsharing/hsadminng/hs/office/partner/HsOfficePartnerRbacRepositoryIntegrationTest.java b/src/test/java/net/hostsharing/hsadminng/hs/office/partner/HsOfficePartnerRbacRepositoryIntegrationTest.java index d6591322..56b1e036 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/office/partner/HsOfficePartnerRbacRepositoryIntegrationTest.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/office/partner/HsOfficePartnerRbacRepositoryIntegrationTest.java @@ -16,7 +16,7 @@ import org.junit.jupiter.api.Nested; 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.test.context.bean.override.mockito.MockitoBean; // FIXME: use MockitoBean +import org.springframework.test.context.bean.override.mockito.MockitoBean; import org.springframework.context.annotation.Import; import org.springframework.orm.jpa.JpaSystemException; -- 2.39.5 From 4ef2d5b66bee73c8792188577816a60550b0a3f3 Mon Sep 17 00:00:00 2001 From: Michael Hoennig Date: Wed, 15 Jan 2025 09:05:27 +0100 Subject: [PATCH 25/35] fix mapping in HsOfficeCoopSharesTransactionController --- ...OfficeCoopSharesTransactionController.java | 51 +++++++++++++------ 1 file changed, 35 insertions(+), 16 deletions(-) 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 9afef7da..5583d44e 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 @@ -1,13 +1,12 @@ package net.hostsharing.hsadminng.hs.office.coopshares; -import jakarta.persistence.EntityNotFoundException; - import io.micrometer.core.annotation.Timed; import net.hostsharing.hsadminng.context.Context; +import net.hostsharing.hsadminng.errors.MultiValidationException; import net.hostsharing.hsadminng.hs.office.generated.api.v1.api.HsOfficeCoopSharesApi; import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeCoopSharesTransactionInsertResource; import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeCoopSharesTransactionResource; -import net.hostsharing.hsadminng.errors.MultiValidationException; +import net.hostsharing.hsadminng.hs.office.membership.HsOfficeMembershipRepository; import net.hostsharing.hsadminng.mapper.StrictMapper; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.format.annotation.DateTimeFormat; @@ -25,6 +24,7 @@ import java.util.function.BiConsumer; import static net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeCoopSharesTransactionTypeResource.CANCELLATION; import static net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeCoopSharesTransactionTypeResource.SUBSCRIPTION; +import static net.hostsharing.hsadminng.hs.validation.UuidResolver.resolve; @RestController public class HsOfficeCoopSharesTransactionController implements HsOfficeCoopSharesApi { @@ -38,6 +38,9 @@ public class HsOfficeCoopSharesTransactionController implements HsOfficeCoopShar @Autowired private HsOfficeCoopSharesTransactionRepository coopSharesTransactionRepo; + @Autowired + private HsOfficeMembershipRepository membershipRepo; + @Override @Transactional(readOnly = true) @Timed("app.office.coopShares.api.getListOfCoopShares") @@ -54,7 +57,10 @@ public class HsOfficeCoopSharesTransactionController implements HsOfficeCoopShar fromValueDate, toValueDate); - final var resources = mapper.mapList(entities, HsOfficeCoopSharesTransactionResource.class); + final var resources = mapper.mapList( + entities, + HsOfficeCoopSharesTransactionResource.class, + ENTITY_TO_RESOURCE_POSTMAPPER); return ResponseEntity.ok(resources); } @@ -69,7 +75,10 @@ public class HsOfficeCoopSharesTransactionController implements HsOfficeCoopShar context.define(currentSubject, assumedRoles); validate(requestBody); - final var entityToSave = mapper.map(requestBody, HsOfficeCoopSharesTransactionEntity.class, RESOURCE_TO_ENTITY_POSTMAPPER); + final var entityToSave = mapper.map( + requestBody, + HsOfficeCoopSharesTransactionEntity.class, + RESOURCE_TO_ENTITY_POSTMAPPER); final var saved = coopSharesTransactionRepo.save(entityToSave); @@ -78,7 +87,7 @@ public class HsOfficeCoopSharesTransactionController implements HsOfficeCoopShar .path("/api/hs/office/coopsharestransactions/{id}") .buildAndExpand(saved.getUuid()) .toUri(); - final var mapped = mapper.map(saved, HsOfficeCoopSharesTransactionResource.class); + final var mapped = mapper.map(saved, HsOfficeCoopSharesTransactionResource.class, ENTITY_TO_RESOURCE_POSTMAPPER); return ResponseEntity.created(uri).body(mapped); } @@ -86,15 +95,18 @@ public class HsOfficeCoopSharesTransactionController implements HsOfficeCoopShar @Transactional(readOnly = true) @Timed("app.office.coopShares.repo.getSingleCoopShareTransactionByUuid") public ResponseEntity getSingleCoopShareTransactionByUuid( - final String currentSubject, final String assumedRoles, final UUID shareTransactionUuid) { + final String currentSubject, final String assumedRoles, final UUID shareTransactionUuid) { - context.define(currentSubject, assumedRoles); + context.define(currentSubject, assumedRoles); - final var result = coopSharesTransactionRepo.findByUuid(shareTransactionUuid); - if (result.isEmpty()) { - return ResponseEntity.notFound().build(); - } - return ResponseEntity.ok(mapper.map(result.get(), HsOfficeCoopSharesTransactionResource.class)); + final var result = coopSharesTransactionRepo.findByUuid(shareTransactionUuid); + if (result.isEmpty()) { + return ResponseEntity.notFound().build(); + } + return ResponseEntity.ok(mapper.map( + result.get(), + HsOfficeCoopSharesTransactionResource.class, + ENTITY_TO_RESOURCE_POSTMAPPER)); } @@ -136,9 +148,16 @@ public class HsOfficeCoopSharesTransactionController implements HsOfficeCoopShar } final BiConsumer RESOURCE_TO_ENTITY_POSTMAPPER = (resource, entity) -> { - if ( resource.getRevertedShareTxUuid() != null ) { - entity.setRevertedShareTx(coopSharesTransactionRepo.findByUuid(resource.getRevertedShareTxUuid()) - .orElseThrow(() -> new EntityNotFoundException("ERROR: [400] revertedShareTxUuid %s not found".formatted(resource.getRevertedShareTxUuid())))); + entity.setMembership(resolve("membership.uuid", resource.getMembershipUuid(), membershipRepo::findByUuid)); + if (resource.getRevertedShareTxUuid() != null) { + entity.setRevertedShareTx(resolve( + "revertedShareTx.uuid", + resource.getRevertedShareTxUuid(), + coopSharesTransactionRepo::findByUuid)); } }; + + final BiConsumer ENTITY_TO_RESOURCE_POSTMAPPER = (entity, resource) -> { + resource.setMembershipUuid(entity.getMembership().getUuid()); + }; } -- 2.39.5 From c85d47c2377a547b95a943aec3b5af7fad37f687 Mon Sep 17 00:00:00 2001 From: Michael Hoennig Date: Wed, 15 Jan 2025 09:06:03 +0100 Subject: [PATCH 26/35] cleanup --- build.gradle | 3 ++- .../coopshares/HsOfficeCoopSharesTransactionEntity.java | 1 + .../hs/office/membership/HsOfficeMembershipController.java | 2 +- .../511-coopshares/5118-hs-office-coopshares-test-data.sql | 5 ++++- .../512-coopassets/5128-hs-office-coopassets-test-data.sql | 5 ++++- 5 files changed, 12 insertions(+), 4 deletions(-) diff --git a/build.gradle b/build.gradle index 39c61aa2..96fbccd3 100644 --- a/build.gradle +++ b/build.gradle @@ -20,7 +20,8 @@ wrapper { gradleVersion = '8.5' } -// FIXME: Mockito is currently self-attaching to enable the inline-mock-maker. This will no longer work in future releases of the JDK. Please add Mockito as an agent to your build what is described in Mockito's documentation: https://javadoc.io/doc/org.mockito/mockito-core/latest/org/mockito/Mockito.html#0.3 +// TODO.impl: self-attaching is deprecated, see: +// https://javadoc.io/doc/org.mockito/mockito-core/latest/org/mockito/Mockito.html#0.3 configurations { compileOnly { 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 7b79bc15..fcc900f1 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 @@ -142,6 +142,7 @@ public class HsOfficeCoopSharesTransactionEntity implements Stringifyable, BaseE directlyFetchedByDependsOnColumn(), NOT_NULL) + // the membership:ADMIN is not to be confused with the member itself, it's an account manager of the coop .toRole("membership", ADMIN).grantPermission(INSERT) .toRole("membership", ADMIN).grantPermission(UPDATE) .toRole("membership", AGENT).grantPermission(SELECT); 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 61ce652b..edf5d0a6 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 @@ -169,7 +169,7 @@ public class HsOfficeMembershipController implements HsOfficeMembershipsApi { if (entity.getValidity().hasUpperBound()) { resource.setValidTo(entity.getValidity().upper().minusDays(1)); } - resource.getPartner().setPartnerNumber(entity.getPartner().getTaggedPartnerNumber()); // FIXME: use partner mapper? + resource.getPartner().setPartnerNumber(entity.getPartner().getTaggedPartnerNumber()); // TODO.refa: use partner mapper? }; final BiConsumer SEPA_MANDATE_RESOURCE_TO_ENTITY_POSTMAPPER = (resource, entity) -> { diff --git a/src/main/resources/db/changelog/5-hs-office/511-coopshares/5118-hs-office-coopshares-test-data.sql b/src/main/resources/db/changelog/5-hs-office/511-coopshares/5118-hs-office-coopshares-test-data.sql index e7229595..5dd06009 100644 --- a/src/main/resources/db/changelog/5-hs-office/511-coopshares/5118-hs-office-coopshares-test-data.sql +++ b/src/main/resources/db/changelog/5-hs-office/511-coopshares/5118-hs-office-coopshares-test-data.sql @@ -43,7 +43,10 @@ end; $$; do language plpgsql $$ begin - call base.defineContext('creating coopSharesTransaction test-data'); + call base.defineContext('creating coopSharesTransaction test-data', + null, + 'superuser-alex@hostsharing.net', + 'rbac.global#global:ADMIN'); SET CONSTRAINTS ALL DEFERRED; call hs_office.coopsharetx_create_test_data(10001, '01'); diff --git a/src/main/resources/db/changelog/5-hs-office/512-coopassets/5128-hs-office-coopassets-test-data.sql b/src/main/resources/db/changelog/5-hs-office/512-coopassets/5128-hs-office-coopassets-test-data.sql index ce94ddfc..2ce3186b 100644 --- a/src/main/resources/db/changelog/5-hs-office/512-coopassets/5128-hs-office-coopassets-test-data.sql +++ b/src/main/resources/db/changelog/5-hs-office/512-coopassets/5128-hs-office-coopassets-test-data.sql @@ -49,7 +49,10 @@ end; $$; do language plpgsql $$ begin - call base.defineContext('creating coopAssetsTransaction test-data'); + call base.defineContext('creating coopAssetsTransaction test-data', + null, + 'superuser-alex@hostsharing.net', + 'rbac.global#global:ADMIN'); SET CONSTRAINTS ALL DEFERRED; call hs_office.coopassettx_create_test_data(10001, '01'); -- 2.39.5 From c8eb5f86d4afdda63a9a7404c347806097b9e8a5 Mon Sep 17 00:00:00 2001 From: Michael Hoennig Date: Wed, 15 Jan 2025 09:07:31 +0100 Subject: [PATCH 27/35] fix RbacGrantsDiagramService to support multiple INSERT permissions --- .../rbac/grant/RbacGrantsDiagramService.java | 72 ++++++++++++------- 1 file changed, 45 insertions(+), 27 deletions(-) diff --git a/src/main/java/net/hostsharing/hsadminng/rbac/grant/RbacGrantsDiagramService.java b/src/main/java/net/hostsharing/hsadminng/rbac/grant/RbacGrantsDiagramService.java index 6a15464d..7e0c7d4c 100644 --- a/src/main/java/net/hostsharing/hsadminng/rbac/grant/RbacGrantsDiagramService.java +++ b/src/main/java/net/hostsharing/hsadminng/rbac/grant/RbacGrantsDiagramService.java @@ -30,7 +30,7 @@ public class RbacGrantsDiagramService { try (BufferedWriter writer = new BufferedWriter(new FileWriter(fileName))) { writer.write(""" ### all grants to %s - + ```mermaid %s ``` @@ -49,8 +49,18 @@ public class RbacGrantsDiagramService { NON_TEST_ENTITIES; public static final EnumSet ALL = EnumSet.allOf(Include.class); - public static final EnumSet ALL_TEST_ENTITY_RELATED = EnumSet.of(USERS, DETAILS, NOT_ASSUMED, TEST_ENTITIES, PERMISSIONS); - public static final EnumSet ALL_NON_TEST_ENTITY_RELATED = EnumSet.of(USERS, DETAILS, NOT_ASSUMED, NON_TEST_ENTITIES, PERMISSIONS); + public static final EnumSet ALL_TEST_ENTITY_RELATED = EnumSet.of( + USERS, + DETAILS, + NOT_ASSUMED, + TEST_ENTITIES, + PERMISSIONS); + public static final EnumSet ALL_NON_TEST_ENTITY_RELATED = EnumSet.of( + USERS, + DETAILS, + NOT_ASSUMED, + NON_TEST_ENTITIES, + PERMISSIONS); } @Autowired @@ -66,9 +76,9 @@ public class RbacGrantsDiagramService { public String allGrantsTocurrentSubject(final EnumSet includes) { final var graph = new LimitedHashSet(); - for ( UUID subjectUuid: context.fetchCurrentSubjectOrAssumedRolesUuids() ) { + for (UUID subjectUuid : context.fetchCurrentSubjectOrAssumedRolesUuids()) { traverseGrantsTo(graph, subjectUuid, includes); - } + } return toMermaidFlowchart(graph, includes); } @@ -78,7 +88,7 @@ public class RbacGrantsDiagramService { if (!includes.contains(PERMISSIONS) && g.getDescendantIdName().startsWith("perm:")) { return; } - if ( !g.getDescendantIdName().startsWith("role:rbac.global")) { + if (!g.getDescendantIdName().startsWith("role:rbac.global")) { if (!includes.contains(TEST_ENTITIES) && g.getDescendantIdName().contains(":rbactest.")) { return; } @@ -96,12 +106,15 @@ public class RbacGrantsDiagramService { public String allGrantsFrom(final UUID targetObject, final String op, final EnumSet includes) { final var graph = new LimitedHashSet(); - @SuppressWarnings("unchecked") - final var refUuids = (List) em.createNativeQuery("SELECT uuid FROM rbac.permission WHERE objectuuid=:targetObject AND op=:op", List.class) + @SuppressWarnings("unchecked") // List -> List> + final var refUuidLists = (List>) em.createNativeQuery( + "select uuid from rbac.permission where objectUuid=:targetObject and op=:op", + List.class) .setParameter("targetObject", targetObject) .setParameter("op", op) .getResultList(); - refUuids.forEach(refUuid -> traverseGrantsFrom(graph, refUuid, includes)); + refUuidLists.stream().flatMap(Collection::stream) + .forEach(refUuid -> traverseGrantsFrom(graph, refUuid, includes)); return toMermaidFlowchart(graph, includes); } @@ -127,20 +140,20 @@ public class RbacGrantsDiagramService { final var entities = includes.contains(DETAILS) ? graph.stream() - .flatMap(g -> Stream.of( - new Node(g.getAscendantIdName(), g.getAscendingUuid()), - new Node(g.getDescendantIdName(), g.getDescendantUuid())) - ) - .collect(groupingBy(RbacGrantsDiagramService::renderEntityIdName)) - .entrySet().stream() - .map(entity -> "subgraph " + cleanId(entity.getKey()) + renderSubgraph(entity.getKey()) + "\n\n " - + entity.getValue().stream() - .map(n -> renderNode(n.idName(), n.uuid()).replace("\n", "\n ")) - .sorted() - .distinct() - .collect(joining("\n\n "))) - .collect(joining("\n\nend\n\n")) - + "\n\nend\n\n" + .flatMap(g -> Stream.of( + new Node(g.getAscendantIdName(), g.getAscendingUuid()), + new Node(g.getDescendantIdName(), g.getDescendantUuid())) + ) + .collect(groupingBy(RbacGrantsDiagramService::renderEntityIdName)) + .entrySet().stream() + .map(entity -> "subgraph " + cleanId(entity.getKey()) + renderSubgraph(entity.getKey()) + "\n\n " + + entity.getValue().stream() + .map(n -> renderNode(n.idName(), n.uuid()).replace("\n", "\n ")) + .sorted() + .distinct() + .collect(joining("\n\n "))) + .collect(joining("\n\nend\n\n")) + + "\n\nend\n\n" : ""; final var grants = graph.stream() @@ -195,7 +208,7 @@ public class RbacGrantsDiagramService { final var refType = refType(idName); if (refType.equals("user")) { - final var displayName = idName.substring(refType.length()+1); + final var displayName = idName.substring(refType.length() + 1); return "(" + displayName + "\nref:" + uuid + ")"; } if (refType.equals("role")) { @@ -217,15 +230,20 @@ public class RbacGrantsDiagramService { @NotNull private static String cleanId(final String idName) { return idName.replaceAll("@.*", "") - .replace("[", "").replace("]", "").replace("(", "").replace(")", "").replace(",", "").replace(">", ":").replace("|", "_"); + .replace("[", "") + .replace("]", "") + .replace("(", "") + .replace(")", "") + .replace(",", "") + .replace(">", ":") + .replace("|", "_"); } - static class LimitedHashSet extends HashSet { @Override public boolean add(final T t) { - if (size() < GRANT_LIMIT ) { + if (size() < GRANT_LIMIT) { return super.add(t); } else { return false; -- 2.39.5 From 14a5e85368c7527406de539d4731a5271ab28e99 Mon Sep 17 00:00:00 2001 From: Michael Hoennig Date: Wed, 15 Jan 2025 09:07:54 +0100 Subject: [PATCH 28/35] add missing HsOfficeMembershipRepository mock --- .../HsOfficeCoopSharesTransactionControllerRestTest.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/test/java/net/hostsharing/hsadminng/hs/office/coopshares/HsOfficeCoopSharesTransactionControllerRestTest.java b/src/test/java/net/hostsharing/hsadminng/hs/office/coopshares/HsOfficeCoopSharesTransactionControllerRestTest.java index c207960f..60221df4 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/office/coopshares/HsOfficeCoopSharesTransactionControllerRestTest.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/office/coopshares/HsOfficeCoopSharesTransactionControllerRestTest.java @@ -1,6 +1,7 @@ package net.hostsharing.hsadminng.hs.office.coopshares; import net.hostsharing.hsadminng.context.Context; +import net.hostsharing.hsadminng.hs.office.membership.HsOfficeMembershipRepository; import net.hostsharing.hsadminng.mapper.StrictMapper; import net.hostsharing.hsadminng.rbac.test.JsonBuilder; import net.hostsharing.hsadminng.config.DisableSecurityConfig; @@ -41,6 +42,9 @@ class HsOfficeCoopSharesTransactionControllerRestTest { @MockitoBean HsOfficeCoopSharesTransactionRepository coopSharesTransactionRepo; + @MockitoBean + HsOfficeMembershipRepository membershipRepo; + static final String VALID_INSERT_REQUEST_BODY = """ { "membership.uuid": "%s", -- 2.39.5 From fb1226fba16370898bf8b00e96234a634481cd7e Mon Sep 17 00:00:00 2001 From: Michael Hoennig Date: Wed, 15 Jan 2025 09:12:11 +0100 Subject: [PATCH 29/35] add missing HsOfficePartnerRealRepository mock --- .../membership/HsOfficeMembershipControllerRestTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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 eda9a0c8..cd5ac099 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 @@ -3,8 +3,8 @@ 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.partner.HsOfficePartnerRbacEntity; -import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerRbacRepository; import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerRealEntity; +import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerRealRepository; import net.hostsharing.hsadminng.mapper.StrictMapper; import net.hostsharing.hsadminng.persistence.EntityManagerWrapper; import net.hostsharing.hsadminng.config.DisableSecurityConfig; @@ -78,7 +78,7 @@ public class HsOfficeMembershipControllerRestTest { HsOfficeCoopAssetsTransactionRepository coopAssetsTransactionRepo; @MockitoBean - HsOfficePartnerRbacRepository partnerRepo; + HsOfficePartnerRealRepository partnerRepo; @MockitoBean HsOfficeMembershipRepository membershipRepo; -- 2.39.5 From c774676fe64e2848f4cbe4ac6768982f1a899507 Mon Sep 17 00:00:00 2001 From: Michael Hoennig Date: Wed, 15 Jan 2025 10:26:45 +0100 Subject: [PATCH 30/35] fix handleJpaObjectRetrievalFailureExceptionWithDisplayName test --- .../errors/RestResponseEntityExceptionHandlerUnitTest.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/test/java/net/hostsharing/hsadminng/errors/RestResponseEntityExceptionHandlerUnitTest.java b/src/test/java/net/hostsharing/hsadminng/errors/RestResponseEntityExceptionHandlerUnitTest.java index e54eac1e..8675e6f6 100644 --- a/src/test/java/net/hostsharing/hsadminng/errors/RestResponseEntityExceptionHandlerUnitTest.java +++ b/src/test/java/net/hostsharing/hsadminng/errors/RestResponseEntityExceptionHandlerUnitTest.java @@ -81,8 +81,7 @@ class RestResponseEntityExceptionHandlerUnitTest { void handleJpaObjectRetrievalFailureExceptionWithDisplayName() { // given final var givenException = new JpaObjectRetrievalFailureException( - new EntityNotFoundException( - "Unable to find net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerEntity with id 12345-123454") + new EntityNotFoundException("Unable to find Entity with id 12345-123454") ); final var givenWebRequest = mock(WebRequest.class); @@ -91,7 +90,7 @@ class RestResponseEntityExceptionHandlerUnitTest { // then assertThat(errorResponse.getBody().getStatusCode()).isEqualTo(400); - assertThat(errorResponse.getBody().getMessage()).isEqualTo("ERROR: [400] Unable to find Partner with uuid 12345-123454"); + assertThat(errorResponse.getBody().getMessage()).isEqualTo("ERROR: [400] Unable to find Entity with id 12345-123454"); } @Test -- 2.39.5 From c698754a8d9ec8f4f878f499055b5d7077772e55 Mon Sep 17 00:00:00 2001 From: Michael Hoennig Date: Wed, 15 Jan 2025 11:22:58 +0100 Subject: [PATCH 31/35] property test access to partner-details --- ...ePartnerRbacRepositoryIntegrationTest.java | 97 +++++++++++-------- 1 file changed, 55 insertions(+), 42 deletions(-) diff --git a/src/test/java/net/hostsharing/hsadminng/hs/office/partner/HsOfficePartnerRbacRepositoryIntegrationTest.java b/src/test/java/net/hostsharing/hsadminng/hs/office/partner/HsOfficePartnerRbacRepositoryIntegrationTest.java index 56b1e036..2b5dfe1b 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/office/partner/HsOfficePartnerRbacRepositoryIntegrationTest.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/office/partner/HsOfficePartnerRbacRepositoryIntegrationTest.java @@ -6,19 +6,19 @@ import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonRealRepository; import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationRealEntity; import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationRealRepository; import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationType; -import net.hostsharing.hsadminng.rbac.test.ContextBasedTestWithCleanup; import net.hostsharing.hsadminng.rbac.grant.RawRbacGrantRepository; import net.hostsharing.hsadminng.rbac.role.RawRbacObjectRepository; import net.hostsharing.hsadminng.rbac.role.RawRbacRoleRepository; +import net.hostsharing.hsadminng.rbac.test.ContextBasedTestWithCleanup; import net.hostsharing.hsadminng.rbac.test.JpaAttempt; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Nested; 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.test.context.bean.override.mockito.MockitoBean; import org.springframework.context.annotation.Import; import org.springframework.orm.jpa.JpaSystemException; +import org.springframework.test.context.bean.override.mockito.MockitoBean; import jakarta.persistence.EntityManager; import jakarta.persistence.PersistenceContext; @@ -27,17 +27,17 @@ import java.util.Arrays; import java.util.List; import java.util.Objects; +import static net.hostsharing.hsadminng.mapper.Array.from; import static net.hostsharing.hsadminng.rbac.grant.RawRbacGrantEntity.distinctGrantDisplaysOf; import static net.hostsharing.hsadminng.rbac.role.RawRbacObjectEntity.objectDisplaysOf; import static net.hostsharing.hsadminng.rbac.role.RawRbacRoleEntity.distinctRoleNamesOf; -import static net.hostsharing.hsadminng.mapper.Array.from; import static net.hostsharing.hsadminng.rbac.role.RbacRoleType.ADMIN; import static net.hostsharing.hsadminng.rbac.role.RbacRoleType.AGENT; import static net.hostsharing.hsadminng.rbac.test.JpaAttempt.attempt; import static org.assertj.core.api.Assertions.assertThat; @DataJpaTest -@Import( { Context.class, JpaAttempt.class }) +@Import({ Context.class, JpaAttempt.class }) class HsOfficePartnerRbacRepositoryIntegrationTest extends ContextBasedTestWithCleanup { @Autowired @@ -81,14 +81,15 @@ class HsOfficePartnerRbacRepositoryIntegrationTest extends ContextBasedTestWithC final var partnerRel = givenSomeTemporaryHostsharingPartnerRel("Winkler", "first contact"); // when - final var result = attempt(em, () -> { - final var newPartner = HsOfficePartnerRbacEntity.builder() - .partnerNumber(20031) - .partnerRel(partnerRel) - .details(HsOfficePartnerDetailsEntity.builder().build()) - .build(); - return partnerRepo.save(newPartner); - }); + final var result = attempt( + em, () -> { + final var newPartner = HsOfficePartnerRbacEntity.builder() + .partnerNumber(20031) + .partnerRel(partnerRel) + .details(HsOfficePartnerDetailsEntity.builder().build()) + .build(); + return partnerRepo.save(newPartner); + }); // then result.assertSuccessful(); @@ -109,26 +110,27 @@ class HsOfficePartnerRbacRepositoryIntegrationTest extends ContextBasedTestWithC .toList(); // when - attempt(em, () -> { - final var givenPartnerPerson = personRepo.findPersonByOptionalNameLike("Erben Bessler").get(0); - final var givenContact = contactrealRepo.findContactByOptionalCaptionLike("fourth contact").get(0); - final var givenMandantPerson = personRepo.findPersonByOptionalNameLike("Hostsharing eG").get(0); + attempt( + em, () -> { + final var givenPartnerPerson = personRepo.findPersonByOptionalNameLike("Erben Bessler").get(0); + final var givenContact = contactrealRepo.findContactByOptionalCaptionLike("fourth contact").get(0); + final var givenMandantPerson = personRepo.findPersonByOptionalNameLike("Hostsharing eG").get(0); - final var newRelation = HsOfficeRelationRealEntity.builder() - .holder(givenPartnerPerson) - .type(HsOfficeRelationType.PARTNER) - .anchor(givenMandantPerson) - .contact(givenContact) - .build(); - relationRepo.save(newRelation); + final var newRelation = HsOfficeRelationRealEntity.builder() + .holder(givenPartnerPerson) + .type(HsOfficeRelationType.PARTNER) + .anchor(givenMandantPerson) + .contact(givenContact) + .build(); + relationRepo.save(newRelation); - final var newPartner = HsOfficePartnerRbacEntity.builder() - .partnerNumber(20032) - .partnerRel(newRelation) - .details(HsOfficePartnerDetailsEntity.builder().build()) - .build(); - return partnerRepo.save(newPartner); - }).assertSuccessful(); + final var newPartner = HsOfficePartnerRbacEntity.builder() + .partnerNumber(20032) + .partnerRel(newRelation) + .details(HsOfficePartnerDetailsEntity.builder().build()) + .build(); + return partnerRepo.save(newPartner); + }).assertSuccessful(); // then assertThat(distinctRoleNamesOf(rawRoleRepo.findAll())).containsExactlyInAnyOrder(from( @@ -208,29 +210,32 @@ class HsOfficePartnerRbacRepositoryIntegrationTest extends ContextBasedTestWithC } @Test - public void partnerAgent_canViewOnlyRelatedPartnersWithoutDetails() { + public void partnerAgent_canViewOnlyRelatedPartnersWithDetails() { // given: - context("person-FirstGmbH@example.com", + context( + "person-FirstGmbH@example.com", "hs_office.relation#HostsharingeG-with-PARTNER-FirstGmbH:AGENT"); // when: final var result = partnerRepo.findPartnerByOptionalNameLike(null); // then: - exactlyThesePartnersAreReturned(result, "partner(P-10001: LP First GmbH, first contact)"); + exactlyThesePartnersAreReturned(result, + "partner(P-10001: LP First GmbH, first contact)+(partnerDetails(Hamburg, RegNo123456789))"); } @Test public void partnerTenant_canViewRelatedPartnersButWithoutDetails() { // given: - context("person-FirstGmbH@example.com", + context( + "person-FirstGmbH@example.com", "hs_office.relation#HostsharingeG-with-PARTNER-FirstGmbH:TENANT"); // when: final var result = partnerRepo.findPartnerByOptionalNameLike(null); // then: - exactlyThesePartnersAreReturned(result, "partner(P-10001: LP First GmbH, first contact)"); + exactlyThesePartnersAreReturned(result, "partner(P-10001: LP First GmbH, first contact)+null"); } } @@ -238,7 +243,7 @@ class HsOfficePartnerRbacRepositoryIntegrationTest extends ContextBasedTestWithC class FindByNameLike { @Test - public void globalAdmin_withoutAssumedRole_canViewAllPartners() { + public void globalAdmin_withoutAssumedRole_canViewAllPartnersWithDetails() { // given context("superuser-alex@hostsharing.net"); @@ -246,7 +251,8 @@ class HsOfficePartnerRbacRepositoryIntegrationTest extends ContextBasedTestWithC final var result = partnerRepo.findPartnerByOptionalNameLike("third contact"); // then - exactlyThesePartnersAreReturned(result, "partner(P-10003: IF Third OHG, third contact)"); + exactlyThesePartnersAreReturned(result, + "partner(P-10003: IF Third OHG, third contact)+(partnerDetails(Hamburg, RegNo123456789))"); } } @@ -315,7 +321,8 @@ class HsOfficePartnerRbacRepositoryIntegrationTest extends ContextBasedTestWithC // when final var result = jpaAttempt.transacted(() -> { - context("superuser-alex@hostsharing.net", + context( + "superuser-alex@hostsharing.net", givenPartner.getPartnerRel().roleId(AGENT)); givenPartner.getDetails().setBirthName("new birthname"); return partnerRepo.save(givenPartner); @@ -327,7 +334,11 @@ class HsOfficePartnerRbacRepositoryIntegrationTest extends ContextBasedTestWithC private void assertThatPartnerActuallyInDatabase(final HsOfficePartnerRbacEntity saved) { final var found = partnerRepo.findByUuid(saved.getUuid()); - assertThat(found).isNotEmpty().get().isNotSameAs(saved).extracting(HsOfficePartnerRbacEntity::toString).isEqualTo(saved.toString()); + assertThat(found).isNotEmpty() + .get() + .isNotSameAs(saved) + .extracting(HsOfficePartnerRbacEntity::toString) + .isEqualTo(saved.toString()); } private void assertThatPartnerIsVisibleForUserWithRole( @@ -428,7 +439,7 @@ class HsOfficePartnerRbacRepositoryIntegrationTest extends ContextBasedTestWithC select currentTask, targetTable, targetOp, targetdelta->>'partnernumber' from base.tx_journal_v where targettable = 'hs_office.partner'; - """); + """); // when @SuppressWarnings("unchecked") final List customerLogEntries = query.getResultList(); @@ -454,7 +465,7 @@ class HsOfficePartnerRbacRepositoryIntegrationTest extends ContextBasedTestWithC .details(HsOfficePartnerDetailsEntity.builder().build()) .build(); - final var savedPartner = partnerRepo.save(newPartner); + final var savedPartner = partnerRepo.save(newPartner); em.flush(); final var partner = em.find(savedPartner.getClass(), savedPartner.getUuid()); return savedPartner; @@ -478,7 +489,9 @@ class HsOfficePartnerRbacRepositoryIntegrationTest extends ContextBasedTestWithC void exactlyThesePartnersAreReturned(final List actualResult, final String... partnerNames) { assertThat(actualResult) - .extracting(HsOfficePartnerRbacEntity::toString) + .extracting(partner -> + partner.toString() + "+" + + (partner.getDetails() != null ? ("(" + partner.getDetails() + ")") : "null")) .containsExactlyInAnyOrder(partnerNames); } -- 2.39.5 From 40cbc2d90da417d3d064842efdf7aa10df788757 Mon Sep 17 00:00:00 2001 From: Michael Hoennig Date: Wed, 15 Jan 2025 11:23:16 +0100 Subject: [PATCH 32/35] apply useLatestVersions again --- build.gradle | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/build.gradle b/build.gradle index 96fbccd3..984388d9 100644 --- a/build.gradle +++ b/build.gradle @@ -4,8 +4,8 @@ plugins { id 'io.spring.dependency-management' version '1.1.7' id 'io.openapiprocessor.openapi-processor' version '2023.2' id 'com.github.jk1.dependency-license-report' version '2.9' - id "org.owasp.dependencycheck" version "11.1.1" - id "com.diffplug.spotless" version "7.0.1" + id "org.owasp.dependencycheck" version "12.0.0" + id "com.diffplug.spotless" version "7.0.2" id 'jacoco' id 'info.solidsoft.pitest' version '1.15.0' id 'se.patrikerdes.use-latest-versions' version '0.2.18' @@ -64,8 +64,8 @@ dependencies { implementation 'org.springframework.boot:spring-boot-starter-actuator' implementation 'org.springframework.boot:spring-boot-starter-security' implementation 'com.github.gavlyukovskiy:datasource-proxy-spring-boot-starter:1.10.0' - implementation 'org.springdoc:springdoc-openapi:2.8.1' - implementation 'org.postgresql:postgresql:42.7.4' + implementation 'org.springdoc:springdoc-openapi:2.8.3' + implementation 'org.postgresql:postgresql:42.7.5' implementation 'org.liquibase:liquibase-core:4.30.0' implementation 'io.hypersistence:hypersistence-utils-hibernate-63:3.9.0' implementation 'com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.18.2' @@ -74,7 +74,7 @@ dependencies { implementation 'net.java.dev.jna:jna:5.16.0' implementation 'org.modelmapper:modelmapper:3.2.2' implementation 'org.iban4j:iban4j:3.2.10-RELEASE' - implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.8.1' + implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.8.3' implementation 'org.reflections:reflections:0.10.2' compileOnly 'org.projectlombok:lombok' -- 2.39.5 From 382a3d520dc7d5df2737f51a5f11370e86c20e2f Mon Sep 17 00:00:00 2001 From: Michael Hoennig Date: Wed, 15 Jan 2025 13:00:57 +0100 Subject: [PATCH 33/35] add howto Python-script --- .aliases | 4 ++- README.md | 5 +++ bin/howto | 86 ++++++++++++++++++++++++++++++++++++++++++++++++++++ build.gradle | 3 ++ 4 files changed, 97 insertions(+), 1 deletion(-) create mode 100755 bin/howto diff --git a/.aliases b/.aliases index cfd7c284..eb60c71d 100644 --- a/.aliases +++ b/.aliases @@ -93,7 +93,8 @@ alias gw-spotless='./gradlew spotlessApply -x pitest -x test -x :processResource alias gw-test='. .aliases; ./gradlew test' alias gw-check='. .aliases; gw test check -x pitest' -alias cas-curl='bin/cas-curl' +alias howto=bin/howto +alias cas-curl=bin/cas-curl # etc/docker-compose.yml limits CPUs+MEM and includes a PostgreSQL config for analysing slow queries alias gw-importOfficeData-in-docker-compose=' @@ -108,3 +109,4 @@ source .environment alias scenario-reports-upload='./gradlew scenarioTests convertMarkdownToHtml && ssh hsh03-hsngdev@h50.hostsharing.net "rm -f doms/hsngdev.hs-example.de/htdocs-ssl/scenarios/office/*.html" && scp build/doc/scenarios/*.html hsh03-hsngdev@h50.hostsharing.net:doms/hsngdev.hs-example.de/htdocs-ssl/scenarios/office' alias scenario-reports-open='open https://hsngdev.hs-example.de/scenarios/office' + diff --git a/README.md b/README.md index a015f73c..e9f40f79 100644 --- a/README.md +++ b/README.md @@ -617,6 +617,11 @@ Besides the following *How Tos* you can also find several *How Tos* in the sourc grep -r HOWTO src ``` +also try this (assumed you've sourced .aliases): +```sh +howto +``` + ### How to Configure .pgpass for the Default PostgreSQL Database? To access the default database schema as used during development, add this line to your `.pgpass` file in your users home directory: diff --git a/bin/howto b/bin/howto new file mode 100755 index 00000000..0a3b6404 --- /dev/null +++ b/bin/howto @@ -0,0 +1,86 @@ +#!/usr/bin/python3 +import os +import sys +from urllib.parse import urljoin, quote + +def path_to_file_uri(path): + """ + Converts a file path to a file URI. + Handles absolute and relative paths. + """ + abs_path = os.path.abspath(path) + return urljoin("file://", quote(abs_path)) + +def is_binary_file(filepath, chunk_size=1024): + """ + Prüft, ob eine Datei binär ist, indem sie den Inhalt der Datei auf nicht-druckbare Zeichen untersucht. + """ + try: + with open(filepath, "rb") as file: + chunk = file.read(chunk_size) + if b"\0" in chunk: # Nullbyte ist ein typisches Zeichen für Binärdateien + return True + return False + except Exception as e: + print(f"Fehler beim Prüfen, ob Datei binär ist: {filepath}: {e}") + return True + +def search_keywords_in_files(keywords): + if not keywords: + print("Bitte geben Sie mindestens ein Stichwort an.") + sys.exit(1) + + # Allowed comment symbols + comment_symbols = {"//", "#", ";"} + + for root, dirs, files in os.walk("."): + # Ausschließen bestimmter Verzeichnisse + dirs[:] = [d for d in dirs if d not in {".git", "build"}] + + for file in files: + filepath = os.path.join(root, file) + + # Überspringen von Binärdateien + if is_binary_file(filepath): + continue + + try: + with open(filepath, "r", encoding="utf-8") as f: + lines = f.readlines() + + for line_number, line in enumerate(lines, start=1): + stripped_line = line.lstrip() # Entfernt führende Leerzeichen + for symbol in comment_symbols: + if stripped_line.startswith(symbol): + # Entfernt das Kommentarzeichen und nachfolgende Leerzeichen + howtoMatch = stripped_line[len(symbol):].lstrip() + if howtoMatch.startswith(("HOWTO ", "HOWTO: ", "How to ")): + if all(keyword in howtoMatch.lower() for keyword in keywords): + + # Titelzeile ohne Kommentarzeichen + print(howtoMatch.rstrip()) + + # Ausgabe nachfolgender Zeilen mit dem gleichen Kommentar-Präfix + for subsequent_line in lines[line_number:]: + subsequent_line = subsequent_line.lstrip() + if subsequent_line.startswith(symbol): + # Entfernt Kommentarzeichen aus Folgezeilen + print("\t" + subsequent_line[len(symbol):].strip()) + else: + break + + # Link mit Zeilennummer + print(f"--> {path_to_file_uri(filepath)}:{line_number}") + + # Abstand zwischen Matches + print() + break + except Exception as e: + print(f"Fehler beim Lesen der Datei {filepath}: {e}") + +if __name__ == "__main__": + if len(sys.argv) < 2: + print("Verwendung: bin/howto ...") + sys.exit(1) + + search_keywords_in_files([arg.lower() for arg in sys.argv[1:]]) diff --git a/build.gradle b/build.gradle index 984388d9..28fbe7c6 100644 --- a/build.gradle +++ b/build.gradle @@ -12,6 +12,9 @@ plugins { id 'com.github.ben-manes.versions' version '0.51.0' } +// HOWTO: find out which dependency versions are managed by Spring Boot: +// https://docs.spring.io/spring-boot/appendix/dependency-versions/coordinates.html + group = 'net.hostsharing' version = '0.0.1-SNAPSHOT' -- 2.39.5 From 8aa7bc1cded9a7441f0cb8bd45374d7e21670410 Mon Sep 17 00:00:00 2001 From: Michael Hoennig Date: Wed, 15 Jan 2025 13:08:59 +0100 Subject: [PATCH 34/35] more Spring managed versions --- build.gradle | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/build.gradle b/build.gradle index 28fbe7c6..6ba3c5e1 100644 --- a/build.gradle +++ b/build.gradle @@ -68,10 +68,10 @@ dependencies { implementation 'org.springframework.boot:spring-boot-starter-security' implementation 'com.github.gavlyukovskiy:datasource-proxy-spring-boot-starter:1.10.0' implementation 'org.springdoc:springdoc-openapi:2.8.3' - implementation 'org.postgresql:postgresql:42.7.5' - implementation 'org.liquibase:liquibase-core:4.30.0' + implementation 'org.postgresql:postgresql' + implementation 'org.liquibase:liquibase-core' implementation 'io.hypersistence:hypersistence-utils-hibernate-63:3.9.0' - implementation 'com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.18.2' + implementation 'com.fasterxml.jackson.datatype:jackson-datatype-jsr310' implementation 'org.openapitools:jackson-databind-nullable:0.2.6' implementation 'org.apache.commons:commons-text:1.13.0' implementation 'net.java.dev.jna:jna:5.16.0' @@ -95,7 +95,7 @@ dependencies { testImplementation 'org.testcontainers:postgresql' testImplementation 'com.tngtech.archunit:archunit-junit5:1.3.0' testImplementation 'io.rest-assured:spring-mock-mvc' - testImplementation 'org.hamcrest:hamcrest-core:3.0' + testImplementation 'org.hamcrest:hamcrest-core' testImplementation 'org.pitest:pitest-junit5-plugin:1.2.1' testImplementation 'org.junit.jupiter:junit-jupiter-api' testImplementation 'org.wiremock:wiremock-standalone:3.10.0' -- 2.39.5 From 4e01c2a0900a1134c7249c7c231d3908dd1f4ba1 Mon Sep 17 00:00:00 2001 From: Michael Hoennig Date: Wed, 15 Jan 2025 13:27:04 +0100 Subject: [PATCH 35/35] remove unused EntityExistsValidator --- .../debitor/HsOfficeDebitorController.java | 4 -- .../persistence/EntityExistsValidator.java | 38 ------------------- 2 files changed, 42 deletions(-) delete mode 100644 src/main/java/net/hostsharing/hsadminng/persistence/EntityExistsValidator.java 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 6b7dc93e..2e0ff210 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 @@ -12,7 +12,6 @@ import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonRealRepository; import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationRealEntity; import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationRealRepository; import net.hostsharing.hsadminng.mapper.StrictMapper; -import net.hostsharing.hsadminng.persistence.EntityExistsValidator; import org.apache.commons.lang3.Validate; import org.hibernate.Hibernate; import org.springframework.beans.factory.annotation.Autowired; @@ -57,9 +56,6 @@ public class HsOfficeDebitorController implements HsOfficeDebitorsApi { @Autowired private HsOfficeBankAccountRepository bankAccountRepo; - @Autowired - private EntityExistsValidator entityValidator; - @PersistenceContext private EntityManager em; diff --git a/src/main/java/net/hostsharing/hsadminng/persistence/EntityExistsValidator.java b/src/main/java/net/hostsharing/hsadminng/persistence/EntityExistsValidator.java deleted file mode 100644 index 1b29e007..00000000 --- a/src/main/java/net/hostsharing/hsadminng/persistence/EntityExistsValidator.java +++ /dev/null @@ -1,38 +0,0 @@ -package net.hostsharing.hsadminng.persistence; - -import net.hostsharing.hsadminng.errors.DisplayAs.DisplayName; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; - -import jakarta.persistence.Entity; -import jakarta.validation.ValidationException; - -@Service -public class EntityExistsValidator { - - @Autowired - private EntityManagerWrapper em; - - public > void validateEntityExists(final String property, final T entitySkeleton) { - final var foundEntity = em.find(entityClass(entitySkeleton), entitySkeleton.getUuid()); - if ( foundEntity == null) { - throw new ValidationException("Unable to find " + DisplayName.of(entitySkeleton) + " by " + property + ": " + entitySkeleton.getUuid()); - } - } - - private static > Class entityClass(final T entityOrProxy) { - final var entityClass = entityClass(entityOrProxy.getClass()); - if (entityClass == null) { - throw new IllegalArgumentException("@Entity not found in superclass hierarchy of " + entityOrProxy.getClass()); - } - return entityClass; - } - - private static Class entityClass(final Class entityOrProxyClass) { - return entityOrProxyClass.isAnnotationPresent(Entity.class) - ? entityOrProxyClass - : entityOrProxyClass.getSuperclass() == null - ? null - : entityClass(entityOrProxyClass.getSuperclass()); - } -} -- 2.39.5