fix JUnit tests (WIP)

This commit is contained in:
Michael Hoennig 2024-08-05 10:07:27 +02:00
parent 8128f17821
commit 7666901ef3
33 changed files with 99 additions and 83 deletions

View File

@ -46,6 +46,6 @@ public class CustomErrorResponse {
this.path = path; this.path = path;
this.statusCode = status.value(); this.statusCode = status.value();
this.statusPhrase = status.getReasonPhrase(); this.statusPhrase = status.getReasonPhrase();
this.message = message; this.message = message.startsWith("ERROR: [") ? message : "ERROR: [" + statusCode + "] " + message;
} }
} }

View File

@ -0,0 +1,24 @@
package net.hostsharing.hsadminng.errors;
import jakarta.validation.constraints.NotNull;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface DisplayAs {
class DisplayName {
public static String of(final Class<?> clazz) {
final var displayNameAnnot = clazz.getAnnotation(DisplayAs.class);
return displayNameAnnot != null ? displayNameAnnot.value() : clazz.getSimpleName();
}
public static String of(@NotNull final Object instance) {
return of(instance.getClass());
}
}
String value() default "";
}

View File

@ -1,12 +0,0 @@
package net.hostsharing.hsadminng.errors;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface DisplayName {
String value() default "";
}

View File

@ -152,8 +152,8 @@ public class RestResponseEntityExceptionHandler
final var entityName = matcher.group(1); final var entityName = matcher.group(1);
final var entityClass = resolveClass(entityName); final var entityClass = resolveClass(entityName);
if (entityClass.isPresent()) { if (entityClass.isPresent()) {
return (entityClass.get().isAnnotationPresent(DisplayName.class) return (entityClass.get().isAnnotationPresent(DisplayAs.class)
? exceptionMessage.replace(entityName, entityClass.get().getAnnotation(DisplayName.class).value()) ? exceptionMessage.replace(entityName, entityClass.get().getAnnotation(DisplayAs.class).value())
: exceptionMessage.replace(entityName, entityClass.get().getSimpleName())) : exceptionMessage.replace(entityName, entityClass.get().getSimpleName()))
.replace(" with id ", " with uuid "); .replace(" with id ", " with uuid ");
} }

View File

@ -4,7 +4,7 @@ import lombok.AllArgsConstructor;
import lombok.Builder; import lombok.Builder;
import lombok.Getter; import lombok.Getter;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import net.hostsharing.hsadminng.errors.DisplayName; import net.hostsharing.hsadminng.errors.DisplayAs;
import net.hostsharing.hsadminng.stringify.Stringify; import net.hostsharing.hsadminng.stringify.Stringify;
import net.hostsharing.hsadminng.stringify.Stringifyable; import net.hostsharing.hsadminng.stringify.Stringifyable;
@ -23,7 +23,7 @@ import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
@Builder @Builder
@NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor @AllArgsConstructor
@DisplayName("BookingDebitor") @DisplayAs("BookingDebitor")
public class HsBookingDebitorEntity implements Stringifyable { public class HsBookingDebitorEntity implements Stringifyable {
public static final String DEBITOR_NUMBER_TAG = "D-"; public static final String DEBITOR_NUMBER_TAG = "D-";

View File

@ -55,7 +55,6 @@ import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Role.REFERRER;
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Role.TENANT; import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Role.TENANT;
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL.directlyFetchedByDependsOnColumn; import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL.directlyFetchedByDependsOnColumn;
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.rbacViewFor; import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.rbacViewFor;
import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
@Builder @Builder
@Entity @Entity

View File

@ -2,7 +2,7 @@ package net.hostsharing.hsadminng.hs.office.bankaccount;
import lombok.*; import lombok.*;
import lombok.experimental.FieldNameConstants; import lombok.experimental.FieldNameConstants;
import net.hostsharing.hsadminng.errors.DisplayName; import net.hostsharing.hsadminng.errors.DisplayAs;
import net.hostsharing.hsadminng.rbac.rbacobject.BaseEntity; import net.hostsharing.hsadminng.rbac.rbacobject.BaseEntity;
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView; import net.hostsharing.hsadminng.rbac.rbacdef.RbacView;
import net.hostsharing.hsadminng.stringify.Stringify; import net.hostsharing.hsadminng.stringify.Stringify;
@ -26,7 +26,7 @@ import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
@NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor @AllArgsConstructor
@FieldNameConstants @FieldNameConstants
@DisplayName("BankAccount") @DisplayAs("BankAccount")
public class HsOfficeBankAccountEntity implements BaseEntity<HsOfficeBankAccountEntity>, Stringifyable { public class HsOfficeBankAccountEntity implements BaseEntity<HsOfficeBankAccountEntity>, Stringifyable {
private static Stringify<HsOfficeBankAccountEntity> toString = stringify(HsOfficeBankAccountEntity.class, "bankAccount") private static Stringify<HsOfficeBankAccountEntity> toString = stringify(HsOfficeBankAccountEntity.class, "bankAccount")

View File

@ -9,7 +9,7 @@ import lombok.NoArgsConstructor;
import lombok.Setter; import lombok.Setter;
import lombok.experimental.FieldNameConstants; import lombok.experimental.FieldNameConstants;
import lombok.experimental.SuperBuilder; import lombok.experimental.SuperBuilder;
import net.hostsharing.hsadminng.errors.DisplayName; import net.hostsharing.hsadminng.errors.DisplayAs;
import net.hostsharing.hsadminng.mapper.PatchableMapWrapper; import net.hostsharing.hsadminng.mapper.PatchableMapWrapper;
import net.hostsharing.hsadminng.rbac.rbacobject.BaseEntity; import net.hostsharing.hsadminng.rbac.rbacobject.BaseEntity;
import net.hostsharing.hsadminng.stringify.Stringify; import net.hostsharing.hsadminng.stringify.Stringify;
@ -36,7 +36,7 @@ import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
@AllArgsConstructor(access = AccessLevel.PROTECTED) @AllArgsConstructor(access = AccessLevel.PROTECTED)
@SuperBuilder(toBuilder = true) @SuperBuilder(toBuilder = true)
@FieldNameConstants @FieldNameConstants
@DisplayName("Contact") @DisplayAs("Contact")
public class HsOfficeContact implements Stringifyable, BaseEntity<HsOfficeContact> { public class HsOfficeContact implements Stringifyable, BaseEntity<HsOfficeContact> {
private static Stringify<HsOfficeContact> toString = stringify(HsOfficeContact.class, "contact") private static Stringify<HsOfficeContact> toString = stringify(HsOfficeContact.class, "contact")

View File

@ -3,9 +3,8 @@ package net.hostsharing.hsadminng.hs.office.contact;
import lombok.Getter; import lombok.Getter;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import lombok.Setter; import lombok.Setter;
import lombok.experimental.FieldNameConstants;
import lombok.experimental.SuperBuilder; import lombok.experimental.SuperBuilder;
import net.hostsharing.hsadminng.errors.DisplayName; import net.hostsharing.hsadminng.errors.DisplayAs;
import jakarta.persistence.Entity; import jakarta.persistence.Entity;
import jakarta.persistence.Table; import jakarta.persistence.Table;
@ -16,7 +15,7 @@ import jakarta.persistence.Table;
@Setter @Setter
@NoArgsConstructor @NoArgsConstructor
@SuperBuilder(toBuilder = true) @SuperBuilder(toBuilder = true)
@DisplayName("BareContact") @DisplayAs("BareContact")
public class HsOfficeContactBareEntity extends HsOfficeContact { public class HsOfficeContactBareEntity extends HsOfficeContact {
} }

View File

@ -1,9 +1,8 @@
package net.hostsharing.hsadminng.hs.office.contact; package net.hostsharing.hsadminng.hs.office.contact;
import lombok.*; import lombok.*;
import lombok.experimental.FieldNameConstants;
import lombok.experimental.SuperBuilder; import lombok.experimental.SuperBuilder;
import net.hostsharing.hsadminng.errors.DisplayName; import net.hostsharing.hsadminng.errors.DisplayAs;
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView; import net.hostsharing.hsadminng.rbac.rbacdef.RbacView;
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL; import net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL;
@ -22,7 +21,7 @@ import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.rbacViewFor;
@Setter @Setter
@NoArgsConstructor @NoArgsConstructor
@SuperBuilder(toBuilder = true) @SuperBuilder(toBuilder = true)
@DisplayName("RbacContact") @DisplayAs("RbacContact")
public class HsOfficeContactRbacEntity extends HsOfficeContact { public class HsOfficeContactRbacEntity extends HsOfficeContact {
public static RbacView rbac() { public static RbacView rbac() {

View File

@ -6,7 +6,7 @@ import lombok.Builder;
import lombok.Getter; import lombok.Getter;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import lombok.Setter; import lombok.Setter;
import net.hostsharing.hsadminng.errors.DisplayName; import net.hostsharing.hsadminng.errors.DisplayAs;
import net.hostsharing.hsadminng.hs.office.membership.HsOfficeMembershipEntity; import net.hostsharing.hsadminng.hs.office.membership.HsOfficeMembershipEntity;
import net.hostsharing.hsadminng.rbac.rbacobject.BaseEntity; import net.hostsharing.hsadminng.rbac.rbacobject.BaseEntity;
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView; import net.hostsharing.hsadminng.rbac.rbacdef.RbacView;
@ -40,7 +40,7 @@ import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
@Builder @Builder
@NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor @AllArgsConstructor
@DisplayName("CoopAssetsTransaction") @DisplayAs("CoopAssetsTransaction")
public class HsOfficeCoopAssetsTransactionEntity implements Stringifyable, BaseEntity<HsOfficeCoopAssetsTransactionEntity> { public class HsOfficeCoopAssetsTransactionEntity implements Stringifyable, BaseEntity<HsOfficeCoopAssetsTransactionEntity> {
private static Stringify<HsOfficeCoopAssetsTransactionEntity> stringify = stringify(HsOfficeCoopAssetsTransactionEntity.class) private static Stringify<HsOfficeCoopAssetsTransactionEntity> stringify = stringify(HsOfficeCoopAssetsTransactionEntity.class)

View File

@ -5,7 +5,7 @@ import lombok.Builder;
import lombok.Getter; import lombok.Getter;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import lombok.Setter; import lombok.Setter;
import net.hostsharing.hsadminng.errors.DisplayName; import net.hostsharing.hsadminng.errors.DisplayAs;
import net.hostsharing.hsadminng.hs.office.membership.HsOfficeMembershipEntity; import net.hostsharing.hsadminng.hs.office.membership.HsOfficeMembershipEntity;
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView; import net.hostsharing.hsadminng.rbac.rbacdef.RbacView;
import net.hostsharing.hsadminng.rbac.rbacobject.BaseEntity; import net.hostsharing.hsadminng.rbac.rbacobject.BaseEntity;
@ -38,7 +38,7 @@ import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
@Builder @Builder
@NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor @AllArgsConstructor
@DisplayName("CoopShareTransaction") @DisplayAs("CoopShareTransaction")
public class HsOfficeCoopSharesTransactionEntity implements Stringifyable, BaseEntity<HsOfficeCoopSharesTransactionEntity> { public class HsOfficeCoopSharesTransactionEntity implements Stringifyable, BaseEntity<HsOfficeCoopSharesTransactionEntity> {
private static Stringify<HsOfficeCoopSharesTransactionEntity> stringify = stringify(HsOfficeCoopSharesTransactionEntity.class) private static Stringify<HsOfficeCoopSharesTransactionEntity> stringify = stringify(HsOfficeCoopSharesTransactionEntity.class)

View File

@ -18,11 +18,12 @@ import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.mvc.method.annotation.MvcUriComponentsBuilder; import org.springframework.web.servlet.mvc.method.annotation.MvcUriComponentsBuilder;
import jakarta.persistence.EntityManager; import jakarta.persistence.EntityManager;
import jakarta.persistence.EntityNotFoundException;
import jakarta.persistence.PersistenceContext; import jakarta.persistence.PersistenceContext;
import jakarta.validation.ValidationException;
import java.util.List; import java.util.List;
import java.util.UUID; import java.util.UUID;
import static net.hostsharing.hsadminng.errors.DisplayAs.DisplayName;
import static net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationType.DEBITOR; import static net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationType.DEBITOR;
@RestController @RestController
@ -92,7 +93,7 @@ public class HsOfficeDebitorController implements HsOfficeDebitorsApi {
final var debitorRelOptional = relBareRepo.findByUuid(body.getDebitorRelUuid()); final var debitorRelOptional = relBareRepo.findByUuid(body.getDebitorRelUuid());
debitorRelOptional.ifPresentOrElse( debitorRelOptional.ifPresentOrElse(
debitorRel -> {entityToSave.setDebitorRel(relBareRepo.save(debitorRel));}, debitorRel -> {entityToSave.setDebitorRel(relBareRepo.save(debitorRel));},
() -> { throw new EntityNotFoundException("ERROR: [400] debitorRelUuid not found: " + body.getDebitorRelUuid());}); () -> { throw new ValidationException("Unable to find BareRelation by debitorRelUuid: " + body.getDebitorRelUuid());});
} }
final var savedEntity = debitorRepo.save(entityToSave); final var savedEntity = debitorRepo.save(entityToSave);
@ -164,7 +165,7 @@ public class HsOfficeDebitorController implements HsOfficeDebitorsApi {
private <T extends BaseEntity<T>> T validateEntityExists(final String property, final T entitySkeleton) { private <T extends BaseEntity<T>> T validateEntityExists(final String property, final T entitySkeleton) {
final var foundEntity = em.find(entitySkeleton.getClass(), entitySkeleton.getUuid()); final var foundEntity = em.find(entitySkeleton.getClass(), entitySkeleton.getUuid());
if ( foundEntity == null) { if ( foundEntity == null) {
throw new EntityNotFoundException("ERROR: [400] " + property + " not found: " + entitySkeleton.getUuid()); throw new ValidationException("Unable to find " + DisplayName.of(entitySkeleton) + " by " + property + ": " + entitySkeleton.getUuid());
} }
//noinspection unchecked //noinspection unchecked

View File

@ -5,7 +5,7 @@ import lombok.Builder;
import lombok.Getter; import lombok.Getter;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import lombok.Setter; import lombok.Setter;
import net.hostsharing.hsadminng.errors.DisplayName; import net.hostsharing.hsadminng.errors.DisplayAs;
import net.hostsharing.hsadminng.hs.office.bankaccount.HsOfficeBankAccountEntity; import net.hostsharing.hsadminng.hs.office.bankaccount.HsOfficeBankAccountEntity;
import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerEntity; import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerEntity;
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelation; import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelation;
@ -59,7 +59,7 @@ import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
@Builder(toBuilder = true) @Builder(toBuilder = true)
@NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor @AllArgsConstructor
@DisplayName("Debitor") @DisplayAs("Debitor")
public class HsOfficeDebitorEntity implements BaseEntity<HsOfficeDebitorEntity>, Stringifyable { public class HsOfficeDebitorEntity implements BaseEntity<HsOfficeDebitorEntity>, Stringifyable {
public static final String DEBITOR_NUMBER_TAG = "D-"; public static final String DEBITOR_NUMBER_TAG = "D-";

View File

@ -7,7 +7,7 @@ import lombok.Builder;
import lombok.Getter; import lombok.Getter;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import lombok.Setter; import lombok.Setter;
import net.hostsharing.hsadminng.errors.DisplayName; import net.hostsharing.hsadminng.errors.DisplayAs;
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationRbacEntity; import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationRbacEntity;
import net.hostsharing.hsadminng.rbac.rbacobject.BaseEntity; import net.hostsharing.hsadminng.rbac.rbacobject.BaseEntity;
import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerEntity; import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerEntity;
@ -61,7 +61,7 @@ import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
@Builder @Builder
@NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor @AllArgsConstructor
@DisplayName("Membership") @DisplayAs("Membership")
public class HsOfficeMembershipEntity implements BaseEntity<HsOfficeMembershipEntity>, Stringifyable { public class HsOfficeMembershipEntity implements BaseEntity<HsOfficeMembershipEntity>, Stringifyable {
public static final String MEMBER_NUMBER_TAG = "M-"; public static final String MEMBER_NUMBER_TAG = "M-";

View File

@ -9,7 +9,6 @@ import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficePartne
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficePartnerResource; import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficePartnerResource;
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficePartnerRelInsertResource; import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficePartnerRelInsertResource;
import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonEntity; import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonEntity;
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelation;
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationBareEntity; import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationBareEntity;
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationBareRepository; import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationBareRepository;
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationType; import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationType;

View File

@ -1,7 +1,7 @@
package net.hostsharing.hsadminng.hs.office.partner; package net.hostsharing.hsadminng.hs.office.partner;
import lombok.*; import lombok.*;
import net.hostsharing.hsadminng.errors.DisplayName; import net.hostsharing.hsadminng.errors.DisplayAs;
import net.hostsharing.hsadminng.rbac.rbacobject.BaseEntity; import net.hostsharing.hsadminng.rbac.rbacobject.BaseEntity;
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView; import net.hostsharing.hsadminng.rbac.rbacdef.RbacView;
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL; import net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL;
@ -25,7 +25,7 @@ import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
@Builder @Builder
@NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor @AllArgsConstructor
@DisplayName("PartnerDetails") @DisplayAs("PartnerDetails")
public class HsOfficePartnerDetailsEntity implements BaseEntity<HsOfficePartnerDetailsEntity>, Stringifyable { public class HsOfficePartnerDetailsEntity implements BaseEntity<HsOfficePartnerDetailsEntity>, Stringifyable {
private static Stringify<HsOfficePartnerDetailsEntity> stringify = stringify( private static Stringify<HsOfficePartnerDetailsEntity> stringify = stringify(

View File

@ -5,7 +5,7 @@ import lombok.Builder;
import lombok.Getter; import lombok.Getter;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import lombok.Setter; import lombok.Setter;
import net.hostsharing.hsadminng.errors.DisplayName; import net.hostsharing.hsadminng.errors.DisplayAs;
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContact; import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContact;
import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonEntity; import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonEntity;
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationBareEntity; import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationBareEntity;
@ -41,7 +41,7 @@ import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
@Builder @Builder
@NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor @AllArgsConstructor
@DisplayName("Partner") @DisplayAs("Partner")
public class HsOfficePartnerEntity implements Stringifyable, BaseEntity<HsOfficePartnerEntity> { public class HsOfficePartnerEntity implements Stringifyable, BaseEntity<HsOfficePartnerEntity> {
public static final String PARTNER_NUMBER_TAG = "P-"; public static final String PARTNER_NUMBER_TAG = "P-";

View File

@ -2,7 +2,7 @@ package net.hostsharing.hsadminng.hs.office.person;
import lombok.*; import lombok.*;
import lombok.experimental.FieldNameConstants; import lombok.experimental.FieldNameConstants;
import net.hostsharing.hsadminng.errors.DisplayName; import net.hostsharing.hsadminng.errors.DisplayAs;
import net.hostsharing.hsadminng.rbac.rbacobject.BaseEntity; import net.hostsharing.hsadminng.rbac.rbacobject.BaseEntity;
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView; import net.hostsharing.hsadminng.rbac.rbacdef.RbacView;
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL; import net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL;
@ -29,7 +29,7 @@ import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
@NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor @AllArgsConstructor
@FieldNameConstants @FieldNameConstants
@DisplayName("Person") @DisplayAs("Person")
public class HsOfficePersonEntity implements BaseEntity<HsOfficePersonEntity>, Stringifyable { public class HsOfficePersonEntity implements BaseEntity<HsOfficePersonEntity>, Stringifyable {
private static Stringify<HsOfficePersonEntity> toString = stringify(HsOfficePersonEntity.class, "person") private static Stringify<HsOfficePersonEntity> toString = stringify(HsOfficePersonEntity.class, "person")

View File

@ -4,7 +4,7 @@ import lombok.Getter;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import lombok.Setter; import lombok.Setter;
import lombok.experimental.SuperBuilder; import lombok.experimental.SuperBuilder;
import net.hostsharing.hsadminng.errors.DisplayName; import net.hostsharing.hsadminng.errors.DisplayAs;
import jakarta.persistence.Entity; import jakarta.persistence.Entity;
import jakarta.persistence.Table; import jakarta.persistence.Table;
@ -16,6 +16,6 @@ import jakarta.persistence.Table;
@Getter @Getter
@Setter @Setter
@SuperBuilder(toBuilder = true) @SuperBuilder(toBuilder = true)
@DisplayName("BareRelation") @DisplayAs("BareRelation")
public class HsOfficeRelationBareEntity extends HsOfficeRelation { public class HsOfficeRelationBareEntity extends HsOfficeRelation {
} }

View File

@ -4,7 +4,7 @@ import lombok.Getter;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import lombok.Setter; import lombok.Setter;
import lombok.experimental.SuperBuilder; import lombok.experimental.SuperBuilder;
import net.hostsharing.hsadminng.errors.DisplayName; import net.hostsharing.hsadminng.errors.DisplayAs;
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactRbacEntity; import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactRbacEntity;
import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonEntity; import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonEntity;
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView; import net.hostsharing.hsadminng.rbac.rbacdef.RbacView;
@ -39,7 +39,7 @@ import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.rbacViewFor;
@Getter @Getter
@Setter @Setter
@SuperBuilder(toBuilder = true) @SuperBuilder(toBuilder = true)
@DisplayName("RbacRelation") @DisplayAs("RbacRelation")
public class HsOfficeRelationRbacEntity extends HsOfficeRelation { public class HsOfficeRelationRbacEntity extends HsOfficeRelation {
public static RbacView rbac() { public static RbacView rbac() {

View File

@ -3,7 +3,7 @@ package net.hostsharing.hsadminng.hs.office.sepamandate;
import io.hypersistence.utils.hibernate.type.range.PostgreSQLRangeType; import io.hypersistence.utils.hibernate.type.range.PostgreSQLRangeType;
import io.hypersistence.utils.hibernate.type.range.Range; import io.hypersistence.utils.hibernate.type.range.Range;
import lombok.*; import lombok.*;
import net.hostsharing.hsadminng.errors.DisplayName; import net.hostsharing.hsadminng.errors.DisplayAs;
import net.hostsharing.hsadminng.hs.office.bankaccount.HsOfficeBankAccountEntity; import net.hostsharing.hsadminng.hs.office.bankaccount.HsOfficeBankAccountEntity;
import net.hostsharing.hsadminng.hs.office.debitor.HsOfficeDebitorEntity; import net.hostsharing.hsadminng.hs.office.debitor.HsOfficeDebitorEntity;
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationRbacEntity; import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationRbacEntity;
@ -39,7 +39,7 @@ import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
@Builder @Builder
@NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor @AllArgsConstructor
@DisplayName("SEPA-Mandate") @DisplayAs("SEPA-Mandate")
public class HsOfficeSepaMandateEntity implements Stringifyable, BaseEntity<HsOfficeSepaMandateEntity> { public class HsOfficeSepaMandateEntity implements Stringifyable, BaseEntity<HsOfficeSepaMandateEntity> {
private static Stringify<HsOfficeSepaMandateEntity> stringify = stringify(HsOfficeSepaMandateEntity.class) private static Stringify<HsOfficeSepaMandateEntity> stringify = stringify(HsOfficeSepaMandateEntity.class)

View File

@ -1,6 +1,5 @@
package net.hostsharing.hsadminng.mapper; package net.hostsharing.hsadminng.mapper;
import net.hostsharing.hsadminng.errors.DisplayName;
import org.modelmapper.ModelMapper; import org.modelmapper.ModelMapper;
import org.springframework.util.ReflectionUtils; import org.springframework.util.ReflectionUtils;
@ -13,6 +12,8 @@ import java.util.List;
import java.util.function.BiConsumer; import java.util.function.BiConsumer;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import static net.hostsharing.hsadminng.errors.DisplayAs.DisplayName;
/** /**
* A nicer API for ModelMapper. * A nicer API for ModelMapper.
*/ */
@ -74,9 +75,7 @@ public class Mapper extends ModelMapper {
if (entity != null) { if (entity != null) {
return entity; return entity;
} }
final var displayNameAnnot = entityClass.getAnnotation(DisplayName.class); throw new ValidationException("Unable to find " + DisplayName.of(entityClass) + " by uuid: " + subEntityUuid);
final var displayName = displayNameAnnot != null ? displayNameAnnot.value() : entityClass.getSimpleName();
throw new ValidationException(displayName + " not found: " + subEntityUuid);
} }
public <S, T> T map(final S source, final Class<T> targetClass, final BiConsumer<S, T> postMapper) { public <S, T> T map(final S source, final Class<T> targetClass, final BiConsumer<S, T> postMapper) {

View File

@ -1,6 +1,6 @@
package net.hostsharing.hsadminng.stringify; package net.hostsharing.hsadminng.stringify;
import net.hostsharing.hsadminng.errors.DisplayName; import net.hostsharing.hsadminng.errors.DisplayAs;
import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.NotNull;
import java.util.ArrayList; import java.util.ArrayList;
@ -46,7 +46,7 @@ public final class Stringify<B> {
if (name != null) { if (name != null) {
this.name = name; this.name = name;
} else { } else {
final var displayName = clazz.getAnnotation(DisplayName.class); final var displayName = clazz.getAnnotation(DisplayAs.class);
if (displayName != null) { if (displayName != null) {
this.name = displayName.value(); this.name = displayName.value();
} else { } else {

View File

@ -84,6 +84,7 @@ public class ArchitectureTest {
@ArchTest @ArchTest
@SuppressWarnings("unused") @SuppressWarnings("unused")
public static final ArchRule dontUseImplSuffix = noClasses() public static final ArchRule dontUseImplSuffix = noClasses()
.that().areNotPrivate() // e.g. Lombok SuperBuilder generated classes
.should().haveSimpleNameEndingWith("Impl"); .should().haveSimpleNameEndingWith("Impl");
@ArchTest @ArchTest

View File

@ -40,7 +40,7 @@ class RestResponseEntityExceptionHandlerUnitTest {
// then // then
assertThat(errorResponse.getBody().getStatusCode()).isEqualTo(409); assertThat(errorResponse.getBody().getStatusCode()).isEqualTo(409);
assertThat(errorResponse.getBody().getMessage()).isEqualTo("First Line"); assertThat(errorResponse.getBody().getMessage()).isEqualTo("ERROR: [409] First Line");
} }
@Test @Test
@ -59,7 +59,7 @@ class RestResponseEntityExceptionHandlerUnitTest {
// then // then
assertThat(errorResponse.getBody().getStatusCode()).isEqualTo(400); assertThat(errorResponse.getBody().getStatusCode()).isEqualTo(400);
assertThat(errorResponse.getBody()).isNotNull() assertThat(errorResponse.getBody()).isNotNull()
.extracting(CustomErrorResponse::getMessage).isEqualTo("Second Line"); .extracting(CustomErrorResponse::getMessage).isEqualTo("ERROR: [400] Second Line");
} }
@Test @Test
@ -91,7 +91,7 @@ class RestResponseEntityExceptionHandlerUnitTest {
// then // then
assertThat(errorResponse.getBody().getStatusCode()).isEqualTo(400); assertThat(errorResponse.getBody().getStatusCode()).isEqualTo(400);
assertThat(errorResponse.getBody().getMessage()).isEqualTo("Unable to find Partner with uuid 12345-123454"); assertThat(errorResponse.getBody().getMessage()).isEqualTo("ERROR: [400] Unable to find Partner with uuid 12345-123454");
} }
@Test @Test
@ -109,7 +109,7 @@ class RestResponseEntityExceptionHandlerUnitTest {
// then // then
assertThat(errorResponse.getBody().getStatusCode()).isEqualTo(400); assertThat(errorResponse.getBody().getStatusCode()).isEqualTo(400);
assertThat(errorResponse.getBody().getMessage()).isEqualTo( assertThat(errorResponse.getBody().getMessage()).isEqualTo(
"Unable to find net.hostsharing.hsadminng.WhateverEntity with id 12345-123454"); "ERROR: [400] Unable to find net.hostsharing.hsadminng.WhateverEntity with id 12345-123454");
} }
@Test @Test
@ -125,7 +125,7 @@ class RestResponseEntityExceptionHandlerUnitTest {
// then // then
assertThat(errorResponse.getBody().getStatusCode()).isEqualTo(400); assertThat(errorResponse.getBody().getStatusCode()).isEqualTo(400);
assertThat(errorResponse.getBody().getMessage()).isEqualTo("whatever error message"); assertThat(errorResponse.getBody().getMessage()).isEqualTo("ERROR: [400] whatever error message");
} }
@Test @Test
@ -143,7 +143,7 @@ class RestResponseEntityExceptionHandlerUnitTest {
// then // then
assertThat(errorResponse.getBody().getStatusCode()).isEqualTo(400); assertThat(errorResponse.getBody().getStatusCode()).isEqualTo(400);
assertThat(errorResponse.getBody().getMessage()).isEqualTo("Unable to find NoDisplayNameEntity with uuid 12345-123454"); assertThat(errorResponse.getBody().getMessage()).isEqualTo("ERROR: [400] Unable to find NoDisplayNameEntity with uuid 12345-123454");
} }
@Test @Test
@ -172,7 +172,7 @@ class RestResponseEntityExceptionHandlerUnitTest {
// then // then
assertThat(errorResponse.getBody().getStatusCode()).isEqualTo(404); assertThat(errorResponse.getBody().getStatusCode()).isEqualTo(404);
assertThat(errorResponse.getBody().getMessage()).isEqualTo("some error message"); assertThat(errorResponse.getBody().getMessage()).isEqualTo("ERROR: [404] some error message");
} }
@ParameterizedTest @ParameterizedTest
@ -191,7 +191,7 @@ class RestResponseEntityExceptionHandlerUnitTest {
// then // then
assertThat(errorResponse.getBody().getStatusCode()).isEqualTo(400); assertThat(errorResponse.getBody().getStatusCode()).isEqualTo(400);
assertThat(errorResponse.getBody().getMessage()).isEqualTo("given error message"); assertThat(errorResponse.getBody().getMessage()).isEqualTo("ERROR: [400] given error message");
} }
@Test @Test
@ -218,7 +218,8 @@ class RestResponseEntityExceptionHandlerUnitTest {
.extracting("statusCode").isEqualTo(400); .extracting("statusCode").isEqualTo(400);
assertThat(errorResponse.getBody()) assertThat(errorResponse.getBody())
.extracting("message") .extracting("message")
.isEqualTo("[someField expected to be something but is \"someRejectedValue\"]"); // FYI: the brackets around the message are here because it's actually an array, in this case of size 1
.isEqualTo("ERROR: [400] [someField expected to be something but is \"someRejectedValue\"]");
} }
@Test @Test
@ -232,7 +233,7 @@ class RestResponseEntityExceptionHandlerUnitTest {
// then // then
assertThat(errorResponse.getBody().getStatusCode()).isEqualTo(500); assertThat(errorResponse.getBody().getStatusCode()).isEqualTo(500);
assertThat(errorResponse.getBody().getMessage()).isEqualTo("First Line"); assertThat(errorResponse.getBody().getMessage()).isEqualTo("ERROR: [500] First Line");
} }
@Test @Test

View File

@ -120,7 +120,7 @@ class HsOfficeCoopSharesTransactionControllerRestTest {
.andExpect(status().is4xxClientError()) .andExpect(status().is4xxClientError())
.andExpect(jsonPath("statusCode", is(400))) .andExpect(jsonPath("statusCode", is(400)))
.andExpect(jsonPath("statusPhrase", is("Bad Request"))) .andExpect(jsonPath("statusPhrase", is("Bad Request")))
.andExpect(jsonPath("message", is(testCase.expectedErrorMessage))); .andExpect(jsonPath("message", is("ERROR: [400] " + testCase.expectedErrorMessage)));
} }
} }

View File

@ -405,7 +405,7 @@ class HsOfficeDebitorControllerAcceptanceTest extends ContextBasedTestWithCleanu
.post("http://localhost/api/hs/office/debitors") .post("http://localhost/api/hs/office/debitors")
.then().log().all().assertThat() .then().log().all().assertThat()
.statusCode(400) .statusCode(400)
.body("message", is("ERROR: [400] debitorRel.contactUuid not found: 00000000-0000-0000-0000-000000000000")); .body("message", is("ERROR: [400] Unable to find BareContact by debitorRel.contactUuid: 00000000-0000-0000-0000-000000000000"));
// @formatter:on // @formatter:on
} }
@ -433,7 +433,7 @@ class HsOfficeDebitorControllerAcceptanceTest extends ContextBasedTestWithCleanu
.post("http://localhost/api/hs/office/debitors") .post("http://localhost/api/hs/office/debitors")
.then().log().all().assertThat() .then().log().all().assertThat()
.statusCode(400) .statusCode(400)
.body("message", is("BareRelation not found: 00000000-0000-0000-0000-000000000000")); .body("message", is("ERROR: [400] Unable to find BareRelation by uuid: 00000000-0000-0000-0000-000000000000"));
// @formatter:on // @formatter:on
} }
} }

View File

@ -85,7 +85,8 @@ public class HsOfficeMembershipControllerRestTest {
.andExpect(status().is4xxClientError()) .andExpect(status().is4xxClientError())
.andExpect(jsonPath("statusCode", is(400))) .andExpect(jsonPath("statusCode", is(400)))
.andExpect(jsonPath("statusPhrase", is("Bad Request"))) .andExpect(jsonPath("statusPhrase", is("Bad Request")))
.andExpect(jsonPath("message", is("[partnerUuid must not be null but is \"null\"]"))); // FYI: the brackets around the message are here because it's actually an array, in this case of size 1
.andExpect(jsonPath("message", is("ERROR: [400] [partnerUuid must not be null but is \"null\"]")));
} }
@Test @Test
@ -114,7 +115,7 @@ public class HsOfficeMembershipControllerRestTest {
.andExpect(status().is4xxClientError()) .andExpect(status().is4xxClientError())
.andExpect(jsonPath("statusCode", is(400))) .andExpect(jsonPath("statusCode", is(400)))
.andExpect(jsonPath("statusPhrase", is("Bad Request"))) .andExpect(jsonPath("statusPhrase", is("Bad Request")))
.andExpect(jsonPath("message", is("Partner not found: " + givenPartnerUuid))); .andExpect(jsonPath("message", is("ERROR: [400] Unable to find Partner by uuid: " + givenPartnerUuid)));
} }
@ParameterizedTest @ParameterizedTest

View File

@ -180,7 +180,7 @@ class HsOfficePartnerControllerAcceptanceTest extends ContextBasedTestWithCleanu
.post("http://localhost/api/hs/office/partners") .post("http://localhost/api/hs/office/partners")
.then().log().all().assertThat() .then().log().all().assertThat()
.statusCode(400) .statusCode(400)
.body("message", is("Unable to find " + HsOfficeContactBareEntity.class.getName() + " with id " + GIVEN_NON_EXISTING_UUID)); .body("message", is("ERROR: [400] Unable to find " + HsOfficeContactBareEntity.class.getName() + " with id " + GIVEN_NON_EXISTING_UUID));
// @formatter:on // @formatter:on
} }
@ -218,7 +218,10 @@ class HsOfficePartnerControllerAcceptanceTest extends ContextBasedTestWithCleanu
.post("http://localhost/api/hs/office/partners") .post("http://localhost/api/hs/office/partners")
.then().log().all().assertThat() .then().log().all().assertThat()
.statusCode(400) .statusCode(400)
.body("message", is("Unable to find " + HsOfficePersonEntity.class.getName() + " with id " + GIVEN_NON_EXISTING_UUID)); // TODO.impl: we want this error message:
// .body("message", is("ERROR: [400] Unable to find Person by uuid: " + GIVEN_NON_EXISTING_UUID));
// but ModelMapper creates this error message:
.body("message", is("ERROR: [400] Unable to find " + HsOfficePersonEntity.class.getName() + " with id " + GIVEN_NON_EXISTING_UUID));
// @formatter:on // @formatter:on
} }
} }

View File

@ -195,7 +195,7 @@ class HsOfficeSepaMandateControllerAcceptanceTest extends ContextBasedTestWithCl
.post("http://localhost/api/hs/office/sepamandates") .post("http://localhost/api/hs/office/sepamandates")
.then().log().all().assertThat() .then().log().all().assertThat()
.statusCode(400) .statusCode(400)
.body("message", is("BankAccount not found: 00000000-0000-0000-0000-000000000000")); .body("message", is("ERROR: [400] Unable to find BankAccount by uuid: 00000000-0000-0000-0000-000000000000"));
// @formatter:on // @formatter:on
} }
@ -225,7 +225,7 @@ class HsOfficeSepaMandateControllerAcceptanceTest extends ContextBasedTestWithCl
.post("http://localhost/api/hs/office/sepamandates") .post("http://localhost/api/hs/office/sepamandates")
.then().log().all().assertThat() .then().log().all().assertThat()
.statusCode(400) .statusCode(400)
.body("message", is("Debitor not found: 00000000-0000-0000-0000-000000000000")); .body("message", is("ERROR: [400] Unable to find Debitor by uuid: 00000000-0000-0000-0000-000000000000"));
// @formatter:on // @formatter:on
} }
} }

View File

@ -1,7 +1,7 @@
package net.hostsharing.hsadminng.rbac.test; package net.hostsharing.hsadminng.rbac.test;
import lombok.*; import lombok.*;
import net.hostsharing.hsadminng.errors.DisplayName; import net.hostsharing.hsadminng.errors.DisplayAs;
import net.hostsharing.hsadminng.mapper.Mapper; import net.hostsharing.hsadminng.mapper.Mapper;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith; import org.junit.jupiter.api.extension.ExtendWith;
@ -88,7 +88,7 @@ class MapperUnitTest {
); );
assertThat(exception).isInstanceOf(ValidationException.class) assertThat(exception).isInstanceOf(ValidationException.class)
.hasMessage("Unable to find SubTargetBean1 with uuid " + GIVEN_UUID); .hasMessage("Unable to find SubTargetBean1 by uuid: " + GIVEN_UUID);
} }
@Test @Test
@ -101,7 +101,7 @@ class MapperUnitTest {
); );
assertThat(exception).isInstanceOf(ValidationException.class) assertThat(exception).isInstanceOf(ValidationException.class)
.hasMessage("Unable to find SomeDisplayName with uuid " + GIVEN_UUID); .hasMessage("Unable to find SomeDisplayName by uuid: " + GIVEN_UUID);
} }
@Test @Test
@ -217,7 +217,7 @@ class MapperUnitTest {
@Setter @Setter
@NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor @AllArgsConstructor
@DisplayName("SomeDisplayName") @DisplayAs("SomeDisplayName")
public static class SubTargetBean2 { public static class SubTargetBean2 {
private UUID uuid; private UUID uuid;

View File

@ -175,7 +175,8 @@ class TestCustomerControllerAcceptanceTest {
.statusCode(403) .statusCode(403)
.contentType(ContentType.JSON) .contentType(ContentType.JSON)
.statusCode(403) .statusCode(403)
.body("message", containsString("insert into test_customer not allowed for current subjects {test_customer#xxx:ADMIN}")); .body("message", containsString("ERROR: [403] insert into test_customer "))
.body("message", containsString(" not allowed for current subjects {test_customer#xxx:ADMIN}"));
// @formatter:on // @formatter:on
// finally, the new customer was not created // finally, the new customer was not created
@ -204,7 +205,8 @@ class TestCustomerControllerAcceptanceTest {
.statusCode(403) .statusCode(403)
.contentType(ContentType.JSON) .contentType(ContentType.JSON)
.statusCode(403) .statusCode(403)
.body("message", containsString("ERROR: [403] insert into test_customer not allowed for current subjects {customer-admin@yyy.example.com}")); .body("message", containsString("ERROR: [403] insert into test_customer "))
.body("message", containsString(" not allowed for current subjects"));
// @formatter:on // @formatter:on
// finally, the new customer was not created // finally, the new customer was not created