fixes HTTP GET with multiple values in result array
This commit is contained in:
parent
765b679042
commit
8fc81d8e2b
@ -84,6 +84,7 @@ public class HsOfficeDebitorController implements HsOfficeDebitorsApi {
|
|||||||
"ERROR: [400] debitorRel.mark must be null");
|
"ERROR: [400] debitorRel.mark must be null");
|
||||||
|
|
||||||
final var entityToSave = mapper.map(body, HsOfficeDebitorEntity.class);
|
final var entityToSave = mapper.map(body, HsOfficeDebitorEntity.class);
|
||||||
|
try {
|
||||||
if (body.getDebitorRel() != null) {
|
if (body.getDebitorRel() != null) {
|
||||||
body.getDebitorRel().setType(DEBITOR.name());
|
body.getDebitorRel().setType(DEBITOR.name());
|
||||||
final var debitorRel = mapper.map("debitorRel.", body.getDebitorRel(), HsOfficeRelationRealEntity.class);
|
final var debitorRel = mapper.map("debitorRel.", body.getDebitorRel(), HsOfficeRelationRealEntity.class);
|
||||||
@ -95,9 +96,28 @@ public class HsOfficeDebitorController implements HsOfficeDebitorsApi {
|
|||||||
final var debitorRelOptional = relrealRepo.findByUuid(body.getDebitorRelUuid());
|
final var debitorRelOptional = relrealRepo.findByUuid(body.getDebitorRelUuid());
|
||||||
debitorRelOptional.ifPresentOrElse(
|
debitorRelOptional.ifPresentOrElse(
|
||||||
debitorRel -> {entityToSave.setDebitorRel(relrealRepo.save(debitorRel));},
|
debitorRel -> {entityToSave.setDebitorRel(relrealRepo.save(debitorRel));},
|
||||||
() -> { throw new ValidationException("Unable to find RealRelation by debitorRelUuid: " + body.getDebitorRelUuid());});
|
() -> {
|
||||||
|
throw new ValidationException(
|
||||||
|
"Unable to find RealRelation by debitorRelUuid: " + body.getDebitorRelUuid());
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final var partnerRel = em.createNativeQuery("""
|
||||||
|
SELECT partnerRel.*
|
||||||
|
FROM hs_office.relation AS partnerRel
|
||||||
|
JOIN hs_office.relation AS debitorRel
|
||||||
|
ON debitorRel.type = 'DEBITOR' AND debitorRel.anchorUuid = partnerRel.holderUuid
|
||||||
|
WHERE partnerRel.type = 'PARTNER'
|
||||||
|
AND :NEW_DebitorRelUuid = debitorRel.uuid
|
||||||
|
""").setParameter("NEW_DebitorRelUuid", entityToSave.getDebitorRel().getUuid()).getResultList();
|
||||||
|
|
||||||
|
|
||||||
|
final var debitorRel = em.createNativeQuery("""
|
||||||
|
SELECT debitorRel.*
|
||||||
|
FROM hs_office.relation AS debitorRel
|
||||||
|
WHERE :NEW_DebitorRelUuid = debitorRel.uuid
|
||||||
|
""").setParameter("NEW_DebitorRelUuid", entityToSave.getDebitorRel().getUuid()).getResultList();
|
||||||
|
|
||||||
final var savedEntity = debitorRepo.save(entityToSave);
|
final var savedEntity = debitorRepo.save(entityToSave);
|
||||||
em.flush();
|
em.flush();
|
||||||
em.refresh(savedEntity);
|
em.refresh(savedEntity);
|
||||||
@ -109,6 +129,9 @@ public class HsOfficeDebitorController implements HsOfficeDebitorsApi {
|
|||||||
.toUri();
|
.toUri();
|
||||||
final var mapped = mapper.map(savedEntity, HsOfficeDebitorResource.class);
|
final var mapped = mapper.map(savedEntity, HsOfficeDebitorResource.class);
|
||||||
return ResponseEntity.created(uri).body(mapped);
|
return ResponseEntity.created(uri).body(mapped);
|
||||||
|
} catch (final RuntimeException exc) {
|
||||||
|
throw exc;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package net.hostsharing.hsadminng.reflection;
|
package net.hostsharing.hsadminng.reflection;
|
||||||
|
|
||||||
|
import lombok.SneakyThrows;
|
||||||
import lombok.experimental.UtilityClass;
|
import lombok.experimental.UtilityClass;
|
||||||
|
|
||||||
import java.lang.annotation.Annotation;
|
import java.lang.annotation.Annotation;
|
||||||
@ -11,12 +12,12 @@ import static java.util.Optional.empty;
|
|||||||
@UtilityClass
|
@UtilityClass
|
||||||
public class AnnotationFinder {
|
public class AnnotationFinder {
|
||||||
|
|
||||||
|
@SneakyThrows
|
||||||
public static <T extends Annotation> Optional<T> findCallerAnnotation(
|
public static <T extends Annotation> Optional<T> findCallerAnnotation(
|
||||||
final Class<T> annotationClassToFind,
|
final Class<T> annotationClassToFind,
|
||||||
final Class<? extends Annotation> annotationClassToStopLookup
|
final Class<? extends Annotation> annotationClassToStopLookup
|
||||||
) {
|
) {
|
||||||
for (var element : Thread.currentThread().getStackTrace()) {
|
for (var element : Thread.currentThread().getStackTrace()) {
|
||||||
try {
|
|
||||||
final var clazz = Class.forName(element.getClassName());
|
final var clazz = Class.forName(element.getClassName());
|
||||||
final var method = getMethodFromStackElement(clazz, element);
|
final var method = getMethodFromStackElement(clazz, element);
|
||||||
|
|
||||||
@ -28,15 +29,11 @@ public class AnnotationFinder {
|
|||||||
return empty();
|
return empty();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (final ClassNotFoundException | NoSuchMethodException e) {
|
|
||||||
throw new RuntimeException(e); // FIXME: when does this happen?
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return empty();
|
return empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Method getMethodFromStackElement(Class<?> clazz, StackTraceElement element)
|
private static Method getMethodFromStackElement(Class<?> clazz, StackTraceElement element) {
|
||||||
throws NoSuchMethodException {
|
|
||||||
for (var method : clazz.getDeclaredMethods()) {
|
for (var method : clazz.getDeclaredMethods()) {
|
||||||
if (method.getName().equals(element.getMethodName())) {
|
if (method.getName().equals(element.getMethodName())) {
|
||||||
return method;
|
return method;
|
||||||
|
@ -36,7 +36,7 @@ begin
|
|||||||
call rbac.enterTriggerForObjectUuid(NEW.uuid);
|
call rbac.enterTriggerForObjectUuid(NEW.uuid);
|
||||||
|
|
||||||
SELECT * FROM rbactest.customer WHERE uuid = NEW.customerUuid INTO newCustomer;
|
SELECT * FROM rbactest.customer WHERE uuid = NEW.customerUuid INTO newCustomer;
|
||||||
assert newCustomer.uuid is not null, format('newCustomer must not be null for NEW.customerUuid = %s', NEW.customerUuid);
|
assert newCustomer.uuid is not null, format('newCustomer must not be null for NEW.customerUuid = %s of package', NEW.customerUuid);
|
||||||
|
|
||||||
|
|
||||||
perform rbac.defineRoleWithGrants(
|
perform rbac.defineRoleWithGrants(
|
||||||
@ -102,10 +102,10 @@ begin
|
|||||||
call rbac.enterTriggerForObjectUuid(NEW.uuid);
|
call rbac.enterTriggerForObjectUuid(NEW.uuid);
|
||||||
|
|
||||||
SELECT * FROM rbactest.customer WHERE uuid = OLD.customerUuid INTO oldCustomer;
|
SELECT * FROM rbactest.customer WHERE uuid = OLD.customerUuid INTO oldCustomer;
|
||||||
assert oldCustomer.uuid is not null, format('oldCustomer must not be null for OLD.customerUuid = %s', OLD.customerUuid);
|
assert oldCustomer.uuid is not null, format('oldCustomer must not be null for OLD.customerUuid = %s of package', OLD.customerUuid);
|
||||||
|
|
||||||
SELECT * FROM rbactest.customer WHERE uuid = NEW.customerUuid INTO newCustomer;
|
SELECT * FROM rbactest.customer WHERE uuid = NEW.customerUuid INTO newCustomer;
|
||||||
assert newCustomer.uuid is not null, format('newCustomer must not be null for NEW.customerUuid = %s', NEW.customerUuid);
|
assert newCustomer.uuid is not null, format('newCustomer must not be null for NEW.customerUuid = %s of package', NEW.customerUuid);
|
||||||
|
|
||||||
|
|
||||||
if NEW.customerUuid <> OLD.customerUuid then
|
if NEW.customerUuid <> OLD.customerUuid then
|
||||||
|
@ -36,7 +36,7 @@ begin
|
|||||||
call rbac.enterTriggerForObjectUuid(NEW.uuid);
|
call rbac.enterTriggerForObjectUuid(NEW.uuid);
|
||||||
|
|
||||||
SELECT * FROM rbactest.package WHERE uuid = NEW.packageUuid INTO newPackage;
|
SELECT * FROM rbactest.package WHERE uuid = NEW.packageUuid INTO newPackage;
|
||||||
assert newPackage.uuid is not null, format('newPackage must not be null for NEW.packageUuid = %s', NEW.packageUuid);
|
assert newPackage.uuid is not null, format('newPackage must not be null for NEW.packageUuid = %s of domain', NEW.packageUuid);
|
||||||
|
|
||||||
|
|
||||||
perform rbac.defineRoleWithGrants(
|
perform rbac.defineRoleWithGrants(
|
||||||
@ -98,10 +98,10 @@ begin
|
|||||||
call rbac.enterTriggerForObjectUuid(NEW.uuid);
|
call rbac.enterTriggerForObjectUuid(NEW.uuid);
|
||||||
|
|
||||||
SELECT * FROM rbactest.package WHERE uuid = OLD.packageUuid INTO oldPackage;
|
SELECT * FROM rbactest.package WHERE uuid = OLD.packageUuid INTO oldPackage;
|
||||||
assert oldPackage.uuid is not null, format('oldPackage must not be null for OLD.packageUuid = %s', OLD.packageUuid);
|
assert oldPackage.uuid is not null, format('oldPackage must not be null for OLD.packageUuid = %s of domain', OLD.packageUuid);
|
||||||
|
|
||||||
SELECT * FROM rbactest.package WHERE uuid = NEW.packageUuid INTO newPackage;
|
SELECT * FROM rbactest.package WHERE uuid = NEW.packageUuid INTO newPackage;
|
||||||
assert newPackage.uuid is not null, format('newPackage must not be null for NEW.packageUuid = %s', NEW.packageUuid);
|
assert newPackage.uuid is not null, format('newPackage must not be null for NEW.packageUuid = %s of domain', NEW.packageUuid);
|
||||||
|
|
||||||
|
|
||||||
if NEW.packageUuid <> OLD.packageUuid then
|
if NEW.packageUuid <> OLD.packageUuid then
|
||||||
|
@ -38,13 +38,13 @@ begin
|
|||||||
call rbac.enterTriggerForObjectUuid(NEW.uuid);
|
call rbac.enterTriggerForObjectUuid(NEW.uuid);
|
||||||
|
|
||||||
SELECT * FROM hs_office.person WHERE uuid = NEW.holderUuid INTO newHolderPerson;
|
SELECT * FROM hs_office.person WHERE uuid = NEW.holderUuid INTO newHolderPerson;
|
||||||
assert newHolderPerson.uuid is not null, format('newHolderPerson must not be null for NEW.holderUuid = %s', NEW.holderUuid);
|
assert newHolderPerson.uuid is not null, format('newHolderPerson must not be null for NEW.holderUuid = %s of relation', NEW.holderUuid);
|
||||||
|
|
||||||
SELECT * FROM hs_office.person WHERE uuid = NEW.anchorUuid INTO newAnchorPerson;
|
SELECT * FROM hs_office.person WHERE uuid = NEW.anchorUuid INTO newAnchorPerson;
|
||||||
assert newAnchorPerson.uuid is not null, format('newAnchorPerson must not be null for NEW.anchorUuid = %s', NEW.anchorUuid);
|
assert newAnchorPerson.uuid is not null, format('newAnchorPerson must not be null for NEW.anchorUuid = %s of relation', NEW.anchorUuid);
|
||||||
|
|
||||||
SELECT * FROM hs_office.contact WHERE uuid = NEW.contactUuid INTO newContact;
|
SELECT * FROM hs_office.contact WHERE uuid = NEW.contactUuid INTO newContact;
|
||||||
assert newContact.uuid is not null, format('newContact must not be null for NEW.contactUuid = %s', NEW.contactUuid);
|
assert newContact.uuid is not null, format('newContact must not be null for NEW.contactUuid = %s of relation', NEW.contactUuid);
|
||||||
|
|
||||||
|
|
||||||
perform rbac.defineRoleWithGrants(
|
perform rbac.defineRoleWithGrants(
|
||||||
|
@ -37,10 +37,10 @@ begin
|
|||||||
call rbac.enterTriggerForObjectUuid(NEW.uuid);
|
call rbac.enterTriggerForObjectUuid(NEW.uuid);
|
||||||
|
|
||||||
SELECT * FROM hs_office.relation WHERE uuid = NEW.partnerRelUuid INTO newPartnerRel;
|
SELECT * FROM hs_office.relation WHERE uuid = NEW.partnerRelUuid INTO newPartnerRel;
|
||||||
assert newPartnerRel.uuid is not null, format('newPartnerRel must not be null for NEW.partnerRelUuid = %s', NEW.partnerRelUuid);
|
assert newPartnerRel.uuid is not null, format('newPartnerRel must not be null for NEW.partnerRelUuid = %s of partner', NEW.partnerRelUuid);
|
||||||
|
|
||||||
SELECT * FROM hs_office.partner_details WHERE uuid = NEW.detailsUuid INTO newPartnerDetails;
|
SELECT * FROM hs_office.partner_details WHERE uuid = NEW.detailsUuid INTO newPartnerDetails;
|
||||||
assert newPartnerDetails.uuid is not null, format('newPartnerDetails must not be null for NEW.detailsUuid = %s', NEW.detailsUuid);
|
assert newPartnerDetails.uuid is not null, format('newPartnerDetails must not be null for NEW.detailsUuid = %s of partner', NEW.detailsUuid);
|
||||||
|
|
||||||
call rbac.grantPermissionToRole(rbac.createPermission(NEW.uuid, 'DELETE'), hs_office.relation_OWNER(newPartnerRel));
|
call rbac.grantPermissionToRole(rbac.createPermission(NEW.uuid, 'DELETE'), hs_office.relation_OWNER(newPartnerRel));
|
||||||
call rbac.grantPermissionToRole(rbac.createPermission(NEW.uuid, 'SELECT'), hs_office.relation_TENANT(newPartnerRel));
|
call rbac.grantPermissionToRole(rbac.createPermission(NEW.uuid, 'SELECT'), hs_office.relation_TENANT(newPartnerRel));
|
||||||
@ -96,16 +96,16 @@ begin
|
|||||||
call rbac.enterTriggerForObjectUuid(NEW.uuid);
|
call rbac.enterTriggerForObjectUuid(NEW.uuid);
|
||||||
|
|
||||||
SELECT * FROM hs_office.relation WHERE uuid = OLD.partnerRelUuid INTO oldPartnerRel;
|
SELECT * FROM hs_office.relation WHERE uuid = OLD.partnerRelUuid INTO oldPartnerRel;
|
||||||
assert oldPartnerRel.uuid is not null, format('oldPartnerRel must not be null for OLD.partnerRelUuid = %s', OLD.partnerRelUuid);
|
assert oldPartnerRel.uuid is not null, format('oldPartnerRel must not be null for OLD.partnerRelUuid = %s of partner', OLD.partnerRelUuid);
|
||||||
|
|
||||||
SELECT * FROM hs_office.relation WHERE uuid = NEW.partnerRelUuid INTO newPartnerRel;
|
SELECT * FROM hs_office.relation WHERE uuid = NEW.partnerRelUuid INTO newPartnerRel;
|
||||||
assert newPartnerRel.uuid is not null, format('newPartnerRel must not be null for NEW.partnerRelUuid = %s', NEW.partnerRelUuid);
|
assert newPartnerRel.uuid is not null, format('newPartnerRel must not be null for NEW.partnerRelUuid = %s of partner', NEW.partnerRelUuid);
|
||||||
|
|
||||||
SELECT * FROM hs_office.partner_details WHERE uuid = OLD.detailsUuid INTO oldPartnerDetails;
|
SELECT * FROM hs_office.partner_details WHERE uuid = OLD.detailsUuid INTO oldPartnerDetails;
|
||||||
assert oldPartnerDetails.uuid is not null, format('oldPartnerDetails must not be null for OLD.detailsUuid = %s', OLD.detailsUuid);
|
assert oldPartnerDetails.uuid is not null, format('oldPartnerDetails must not be null for OLD.detailsUuid = %s of partner', OLD.detailsUuid);
|
||||||
|
|
||||||
SELECT * FROM hs_office.partner_details WHERE uuid = NEW.detailsUuid INTO newPartnerDetails;
|
SELECT * FROM hs_office.partner_details WHERE uuid = NEW.detailsUuid INTO newPartnerDetails;
|
||||||
assert newPartnerDetails.uuid is not null, format('newPartnerDetails must not be null for NEW.detailsUuid = %s', NEW.detailsUuid);
|
assert newPartnerDetails.uuid is not null, format('newPartnerDetails must not be null for NEW.detailsUuid = %s of partner', NEW.detailsUuid);
|
||||||
|
|
||||||
|
|
||||||
if NEW.partnerRelUuid <> OLD.partnerRelUuid then
|
if NEW.partnerRelUuid <> OLD.partnerRelUuid then
|
||||||
|
@ -44,10 +44,10 @@ begin
|
|||||||
WHERE partnerRel.type = 'PARTNER'
|
WHERE partnerRel.type = 'PARTNER'
|
||||||
AND NEW.debitorRelUuid = debitorRel.uuid
|
AND NEW.debitorRelUuid = debitorRel.uuid
|
||||||
INTO newPartnerRel;
|
INTO newPartnerRel;
|
||||||
assert newPartnerRel.uuid is not null, format('newPartnerRel must not be null for NEW.debitorRelUuid = %s', NEW.debitorRelUuid);
|
assert newPartnerRel.uuid is not null, format('newPartnerRel must not be null for NEW.debitorRelUuid = %s of debitor', NEW.debitorRelUuid);
|
||||||
|
|
||||||
SELECT * FROM hs_office.relation WHERE uuid = NEW.debitorRelUuid INTO newDebitorRel;
|
SELECT * FROM hs_office.relation WHERE uuid = NEW.debitorRelUuid INTO newDebitorRel;
|
||||||
assert newDebitorRel.uuid is not null, format('newDebitorRel must not be null for NEW.debitorRelUuid = %s', NEW.debitorRelUuid);
|
assert newDebitorRel.uuid is not null, format('newDebitorRel must not be null for NEW.debitorRelUuid = %s of debitor', NEW.debitorRelUuid);
|
||||||
|
|
||||||
SELECT * FROM hs_office.bankaccount WHERE uuid = NEW.refundBankAccountUuid INTO newRefundBankAccount;
|
SELECT * FROM hs_office.bankaccount WHERE uuid = NEW.refundBankAccountUuid INTO newRefundBankAccount;
|
||||||
|
|
||||||
|
@ -37,14 +37,14 @@ begin
|
|||||||
call rbac.enterTriggerForObjectUuid(NEW.uuid);
|
call rbac.enterTriggerForObjectUuid(NEW.uuid);
|
||||||
|
|
||||||
SELECT * FROM hs_office.bankaccount WHERE uuid = NEW.bankAccountUuid INTO newBankAccount;
|
SELECT * FROM hs_office.bankaccount WHERE uuid = NEW.bankAccountUuid INTO newBankAccount;
|
||||||
assert newBankAccount.uuid is not null, format('newBankAccount must not be null for NEW.bankAccountUuid = %s', NEW.bankAccountUuid);
|
assert newBankAccount.uuid is not null, format('newBankAccount must not be null for NEW.bankAccountUuid = %s of sepamandate', NEW.bankAccountUuid);
|
||||||
|
|
||||||
SELECT debitorRel.*
|
SELECT debitorRel.*
|
||||||
FROM hs_office.relation debitorRel
|
FROM hs_office.relation debitorRel
|
||||||
JOIN hs_office.debitor debitor ON debitor.debitorRelUuid = debitorRel.uuid
|
JOIN hs_office.debitor debitor ON debitor.debitorRelUuid = debitorRel.uuid
|
||||||
WHERE debitor.uuid = NEW.debitorUuid
|
WHERE debitor.uuid = NEW.debitorUuid
|
||||||
INTO newDebitorRel;
|
INTO newDebitorRel;
|
||||||
assert newDebitorRel.uuid is not null, format('newDebitorRel must not be null for NEW.debitorUuid = %s', NEW.debitorUuid);
|
assert newDebitorRel.uuid is not null, format('newDebitorRel must not be null for NEW.debitorUuid = %s of sepamandate', NEW.debitorUuid);
|
||||||
|
|
||||||
|
|
||||||
perform rbac.defineRoleWithGrants(
|
perform rbac.defineRoleWithGrants(
|
||||||
|
@ -40,7 +40,7 @@ begin
|
|||||||
JOIN hs_office.relation AS partnerRel ON partnerRel.uuid = partner.partnerRelUuid
|
JOIN hs_office.relation AS partnerRel ON partnerRel.uuid = partner.partnerRelUuid
|
||||||
WHERE partner.uuid = NEW.partnerUuid
|
WHERE partner.uuid = NEW.partnerUuid
|
||||||
INTO newPartnerRel;
|
INTO newPartnerRel;
|
||||||
assert newPartnerRel.uuid is not null, format('newPartnerRel must not be null for NEW.partnerUuid = %s', NEW.partnerUuid);
|
assert newPartnerRel.uuid is not null, format('newPartnerRel must not be null for NEW.partnerUuid = %s of membership', NEW.partnerUuid);
|
||||||
|
|
||||||
|
|
||||||
perform rbac.defineRoleWithGrants(
|
perform rbac.defineRoleWithGrants(
|
||||||
|
@ -36,7 +36,7 @@ begin
|
|||||||
call rbac.enterTriggerForObjectUuid(NEW.uuid);
|
call rbac.enterTriggerForObjectUuid(NEW.uuid);
|
||||||
|
|
||||||
SELECT * FROM hs_office.membership WHERE uuid = NEW.membershipUuid INTO newMembership;
|
SELECT * FROM hs_office.membership WHERE uuid = NEW.membershipUuid INTO newMembership;
|
||||||
assert newMembership.uuid is not null, format('newMembership must not be null for NEW.membershipUuid = %s', NEW.membershipUuid);
|
assert newMembership.uuid is not null, format('newMembership must not be null for NEW.membershipUuid = %s of coopshares', NEW.membershipUuid);
|
||||||
|
|
||||||
call rbac.grantPermissionToRole(rbac.createPermission(NEW.uuid, 'SELECT'), hs_office.membership_AGENT(newMembership));
|
call rbac.grantPermissionToRole(rbac.createPermission(NEW.uuid, 'SELECT'), hs_office.membership_AGENT(newMembership));
|
||||||
call rbac.grantPermissionToRole(rbac.createPermission(NEW.uuid, 'UPDATE'), hs_office.membership_ADMIN(newMembership));
|
call rbac.grantPermissionToRole(rbac.createPermission(NEW.uuid, 'UPDATE'), hs_office.membership_ADMIN(newMembership));
|
||||||
|
@ -36,7 +36,7 @@ begin
|
|||||||
call rbac.enterTriggerForObjectUuid(NEW.uuid);
|
call rbac.enterTriggerForObjectUuid(NEW.uuid);
|
||||||
|
|
||||||
SELECT * FROM hs_office.membership WHERE uuid = NEW.membershipUuid INTO newMembership;
|
SELECT * FROM hs_office.membership WHERE uuid = NEW.membershipUuid INTO newMembership;
|
||||||
assert newMembership.uuid is not null, format('newMembership must not be null for NEW.membershipUuid = %s', NEW.membershipUuid);
|
assert newMembership.uuid is not null, format('newMembership must not be null for NEW.membershipUuid = %s of coopasset', NEW.membershipUuid);
|
||||||
|
|
||||||
call rbac.grantPermissionToRole(rbac.createPermission(NEW.uuid, 'SELECT'), hs_office.membership_AGENT(newMembership));
|
call rbac.grantPermissionToRole(rbac.createPermission(NEW.uuid, 'SELECT'), hs_office.membership_AGENT(newMembership));
|
||||||
call rbac.grantPermissionToRole(rbac.createPermission(NEW.uuid, 'UPDATE'), hs_office.membership_ADMIN(newMembership));
|
call rbac.grantPermissionToRole(rbac.createPermission(NEW.uuid, 'UPDATE'), hs_office.membership_ADMIN(newMembership));
|
||||||
|
@ -37,14 +37,14 @@ begin
|
|||||||
call rbac.enterTriggerForObjectUuid(NEW.uuid);
|
call rbac.enterTriggerForObjectUuid(NEW.uuid);
|
||||||
|
|
||||||
SELECT * FROM hs_office.debitor WHERE uuid = NEW.debitorUuid INTO newDebitor;
|
SELECT * FROM hs_office.debitor WHERE uuid = NEW.debitorUuid INTO newDebitor;
|
||||||
assert newDebitor.uuid is not null, format('newDebitor must not be null for NEW.debitorUuid = %s', NEW.debitorUuid);
|
assert newDebitor.uuid is not null, format('newDebitor must not be null for NEW.debitorUuid = %s of project', NEW.debitorUuid);
|
||||||
|
|
||||||
SELECT debitorRel.*
|
SELECT debitorRel.*
|
||||||
FROM hs_office.relation debitorRel
|
FROM hs_office.relation debitorRel
|
||||||
JOIN hs_office.debitor debitor ON debitor.debitorRelUuid = debitorRel.uuid
|
JOIN hs_office.debitor debitor ON debitor.debitorRelUuid = debitorRel.uuid
|
||||||
WHERE debitor.uuid = NEW.debitorUuid
|
WHERE debitor.uuid = NEW.debitorUuid
|
||||||
INTO newDebitorRel;
|
INTO newDebitorRel;
|
||||||
assert newDebitorRel.uuid is not null, format('newDebitorRel must not be null for NEW.debitorUuid = %s', NEW.debitorUuid);
|
assert newDebitorRel.uuid is not null, format('newDebitorRel must not be null for NEW.debitorUuid = %s or project', NEW.debitorUuid);
|
||||||
|
|
||||||
|
|
||||||
perform rbac.defineRoleWithGrants(
|
perform rbac.defineRoleWithGrants(
|
||||||
|
@ -39,6 +39,8 @@ public abstract class ScenarioTest extends ContextBasedTest {
|
|||||||
@Getter
|
@Getter
|
||||||
private PrintWriter markdownFile;
|
private PrintWriter markdownFile;
|
||||||
|
|
||||||
|
private StringBuilder debugLog = new StringBuilder();
|
||||||
|
|
||||||
record Alias<T extends UseCase<T>>(Class<T> useCase, UUID uuid) {}
|
record Alias<T extends UseCase<T>>(Class<T> useCase, UUID uuid) {}
|
||||||
|
|
||||||
private final static Map<String, Alias<?>> aliases = new HashMap<>();
|
private final static Map<String, Alias<?>> aliases = new HashMap<>();
|
||||||
@ -57,22 +59,37 @@ public abstract class ScenarioTest extends ContextBasedTest {
|
|||||||
@BeforeEach
|
@BeforeEach
|
||||||
void init(final TestInfo testInfo) {
|
void init(final TestInfo testInfo) {
|
||||||
createHostsharingPerson();
|
createHostsharingPerson();
|
||||||
|
try {
|
||||||
testInfo.getTestMethod().ifPresent(this::callRequiredProducers);
|
testInfo.getTestMethod().ifPresent(this::callRequiredProducers);
|
||||||
createTestLogMarkdownFile(testInfo);
|
createTestLogMarkdownFile(testInfo);
|
||||||
|
} catch (Exception exc) {
|
||||||
|
throw exc;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@AfterEach
|
@AfterEach
|
||||||
void cleanup() {
|
void cleanup() {
|
||||||
properties.clear();
|
properties.clear();
|
||||||
|
if (markdownFile != null) {
|
||||||
markdownFile.close();
|
markdownFile.close();
|
||||||
|
} else {
|
||||||
|
toString();
|
||||||
|
}
|
||||||
|
debugLog = new StringBuilder();
|
||||||
}
|
}
|
||||||
|
|
||||||
@SneakyThrows
|
@SneakyThrows
|
||||||
void print(final String output) {
|
void print(final String output) {
|
||||||
|
|
||||||
|
final var outputWithCommentsForUuids = UUIDAppender.appendUUIDKey(aliases, output.replace("+", "\\+"));
|
||||||
|
|
||||||
// for tests executed due to @Requires/@Produces there is no markdownFile yet
|
// for tests executed due to @Requires/@Produces there is no markdownFile yet
|
||||||
if (markdownFile != null) {
|
if (markdownFile != null) {
|
||||||
markdownFile.print(output);
|
markdownFile.print(outputWithCommentsForUuids);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// but the debugLog should contain all output
|
||||||
|
debugLog.append(outputWithCommentsForUuids);
|
||||||
}
|
}
|
||||||
|
|
||||||
void printLine(final String output) {
|
void printLine(final String output) {
|
||||||
|
@ -0,0 +1,34 @@
|
|||||||
|
package net.hostsharing.hsadminng.hs.office.scenarios;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class UUIDAppender {
|
||||||
|
public static String appendUUIDKey(Map<String, ScenarioTest.Alias<?>> uuidMap, String multilineText) {
|
||||||
|
// Split the multiline text into lines
|
||||||
|
String[] lines = multilineText.split("\\r?\\n");
|
||||||
|
|
||||||
|
// StringBuilder to build the resulting multiline text
|
||||||
|
StringBuilder result = new StringBuilder();
|
||||||
|
|
||||||
|
// Iterate over each line
|
||||||
|
for (String line : lines) {
|
||||||
|
|
||||||
|
// Iterate over the map to find if the line contains a UUID
|
||||||
|
for (Map.Entry<String, ScenarioTest.Alias<?>> entry : uuidMap.entrySet()) {
|
||||||
|
String uuidString = entry.getValue().uuid().toString();
|
||||||
|
|
||||||
|
// If the line contains the UUID, append the key at the end
|
||||||
|
if (line.contains(uuidString)) {
|
||||||
|
line = line + " // " + entry.getKey();
|
||||||
|
break; // Exit once we've matched one UUID
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Append the (possibly modified) line to the result
|
||||||
|
result.append(line).append("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return the final modified text
|
||||||
|
return result.toString();
|
||||||
|
}
|
||||||
|
}
|
@ -1,5 +1,6 @@
|
|||||||
package net.hostsharing.hsadminng.hs.office.scenarios;
|
package net.hostsharing.hsadminng.hs.office.scenarios;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.core.type.TypeReference;
|
||||||
import com.fasterxml.jackson.databind.JsonNode;
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import io.restassured.http.ContentType;
|
import io.restassured.http.ContentType;
|
||||||
@ -17,10 +18,10 @@ import java.net.URI;
|
|||||||
import java.net.http.HttpClient;
|
import java.net.http.HttpClient;
|
||||||
import java.net.http.HttpRequest;
|
import java.net.http.HttpRequest;
|
||||||
import java.net.http.HttpRequest.BodyPublishers;
|
import java.net.http.HttpRequest.BodyPublishers;
|
||||||
import java.net.http.HttpResponse;
|
|
||||||
import java.net.http.HttpResponse.BodyHandlers;
|
import java.net.http.HttpResponse.BodyHandlers;
|
||||||
import java.time.Duration;
|
import java.time.Duration;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
@ -67,7 +68,11 @@ public abstract class UseCase<T extends UseCase<?>> {
|
|||||||
|------|-------|""");
|
|------|-------|""");
|
||||||
givenProperties.forEach((key, value) -> printLine("| " + key + " | " + value.toString().replace("\n", "<br>") + " |"));
|
givenProperties.forEach((key, value) -> printLine("| " + key + " | " + value.toString().replace("\n", "<br>") + " |"));
|
||||||
printLine("");
|
printLine("");
|
||||||
requirements.forEach((alias, factory) -> factory.apply(alias).run().keep());
|
requirements.forEach((alias, factory) -> {
|
||||||
|
if (!ScenarioTest.containsAlias(alias)) {
|
||||||
|
factory.apply(alias).run().keep();
|
||||||
|
}
|
||||||
|
});
|
||||||
return run();
|
return run();
|
||||||
}
|
}
|
||||||
protected abstract HttpResponse run();
|
protected abstract HttpResponse run();
|
||||||
@ -144,7 +149,7 @@ public abstract class UseCase<T extends UseCase<?>> {
|
|||||||
.timeout(Duration.ofSeconds(10))
|
.timeout(Duration.ofSeconds(10))
|
||||||
.build();
|
.build();
|
||||||
final var response = client.send(request, BodyHandlers.ofString());
|
final var response = client.send(request, BodyHandlers.ofString());
|
||||||
return new HttpResponse(HttpMethod.PATCH, uriPath, null, response);
|
return new HttpResponse(HttpMethod.DELETE, uriPath, null, response);
|
||||||
}
|
}
|
||||||
|
|
||||||
public final UUID uuid(final String alias) {
|
public final UUID uuid(final String alias) {
|
||||||
@ -240,8 +245,20 @@ public abstract class UseCase<T extends UseCase<?>> {
|
|||||||
new ScenarioTest.Alias<>(UseCase.this.getClass(), locationUuid));
|
new ScenarioTest.Alias<>(UseCase.this.getClass(), locationUuid));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SneakyThrows
|
||||||
|
public HttpResponse expectArrayElements(final int expectedElementCount) {
|
||||||
|
final var rootNode = objectMapper.readTree(response.body());
|
||||||
|
assertThat(rootNode.isArray()).as("array expected, but got: " + response.body()).isTrue();
|
||||||
|
|
||||||
|
final var root = (List<?>) objectMapper.readValue(response.body(), new TypeReference<List<Object>>() {
|
||||||
|
});
|
||||||
|
assertThat(root.size()).as("unexpected number of array elements").isEqualTo(expectedElementCount);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
@SneakyThrows
|
@SneakyThrows
|
||||||
public String getFromBody(final String path) {
|
public String getFromBody(final String path) {
|
||||||
|
// FIXME: use JsonPath: https://www.baeldung.com/guide-to-jayway-jsonpath
|
||||||
final var rootNode = objectMapper.readTree(response.body());
|
final var rootNode = objectMapper.readTree(response.body());
|
||||||
return getPropertyFromJson(rootNode, path);
|
return getPropertyFromJson(rootNode, path);
|
||||||
}
|
}
|
||||||
|
@ -16,9 +16,9 @@ public class CreateSelfDebitorForPartner extends UseCase<CreateSelfDebitorForPar
|
|||||||
@Override
|
@Override
|
||||||
protected HttpResponse run() {
|
protected HttpResponse run() {
|
||||||
keep("partnerPersonUuid", () ->
|
keep("partnerPersonUuid", () ->
|
||||||
httpGet("/api/hs/office/relations?personData=" + uriEncoded("%{partnerPersonTradeName}"))
|
httpGet("/api/hs/office/relations?relationType=PARTNER&personData=" + uriEncoded("%{partnerPersonTradeName}"))
|
||||||
.expecting(OK).expecting(JSON),
|
.expecting(OK).expecting(JSON),
|
||||||
response -> response.getFromBody("[0].holder.uuid")
|
response -> response.expectArrayElements(1).getFromBody("[0].holder.uuid")
|
||||||
);
|
);
|
||||||
printPara("From that output above, we're taking the UUID of the holder of the first result element.");
|
printPara("From that output above, we're taking the UUID of the holder of the first result element.");
|
||||||
printPara("**HINT**: With production data, you might get multiple results and have to decide which is the right one.");
|
printPara("**HINT**: With production data, you might get multiple results and have to decide which is the right one.");
|
||||||
@ -49,7 +49,7 @@ public class CreateSelfDebitorForPartner extends UseCase<CreateSelfDebitorForPar
|
|||||||
return httpPost("/api/hs/office/debitors", usingJsonBody("""
|
return httpPost("/api/hs/office/debitors", usingJsonBody("""
|
||||||
{
|
{
|
||||||
"debitorRel": {
|
"debitorRel": {
|
||||||
"type": "DEBITOR", // FIXME: should be defaulted to DEBITOR
|
"type": "DEBITOR", // TODO.impl: should become defaulted to DEBITOR
|
||||||
"anchorUuid": ${partnerPersonUuid},
|
"anchorUuid": ${partnerPersonUuid},
|
||||||
"holderUuid": ${partnerPersonUuid},
|
"holderUuid": ${partnerPersonUuid},
|
||||||
"contactUuid": ${Contact: Test AG - billing department}
|
"contactUuid": ${Contact: Test AG - billing department}
|
||||||
|
@ -10,7 +10,7 @@ public class DeleteDebitor extends UseCase<DeleteDebitor> {
|
|||||||
super(testSuite);
|
super(testSuite);
|
||||||
|
|
||||||
requires("Debitor: Test AG - delete debitor", alias -> new CreateSelfDebitorForPartner(testSuite, alias)
|
requires("Debitor: Test AG - delete debitor", alias -> new CreateSelfDebitorForPartner(testSuite, alias)
|
||||||
.given("partnerPersonUuid", "%{Person: Test AG}")
|
.given("partnerPersonTradeName", "Test AG")
|
||||||
.given("billingContactCaption", "Test AG - billing department")
|
.given("billingContactCaption", "Test AG - billing department")
|
||||||
.given("billingContactEmailAddress", "billing@test-ag.example.org")
|
.given("billingContactEmailAddress", "billing@test-ag.example.org")
|
||||||
.given("debitorNumberSuffix", "%{debitorSuffix}")
|
.given("debitorNumberSuffix", "%{debitorSuffix}")
|
||||||
|
Loading…
Reference in New Issue
Block a user