Compare commits
1 Commits
fa05234c89
...
01d4821ad3
Author | SHA1 | Date | |
---|---|---|---|
|
01d4821ad3 |
@ -20,7 +20,6 @@ import java.util.UUID;
|
|||||||
import static net.hostsharing.hsadminng.errors.Validate.validate;
|
import static net.hostsharing.hsadminng.errors.Validate.validate;
|
||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
|
|
||||||
public class HsOfficeContactController implements HsOfficeContactsApi {
|
public class HsOfficeContactController implements HsOfficeContactsApi {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
@ -38,6 +37,8 @@ public class HsOfficeContactController implements HsOfficeContactsApi {
|
|||||||
@PostConstruct
|
@PostConstruct
|
||||||
public void init() {
|
public void init() {
|
||||||
// HOWTO: add a ModelMapper converter for a generic entity class to a ModelMapper to be used in a certain context
|
// HOWTO: add a ModelMapper converter for a generic entity class to a ModelMapper to be used in a certain context
|
||||||
|
// This @PostConstruct could be implemented in the converter, but only without generics.
|
||||||
|
// But this converter is for HsOfficeContactRbacEntity and HsOfficeContactRealEntity.
|
||||||
mapper.addConverter(contactFromResourceConverter, HsOfficeContactInsertResource.class, HsOfficeContactRbacEntity.class);
|
mapper.addConverter(contactFromResourceConverter, HsOfficeContactInsertResource.class, HsOfficeContactRbacEntity.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,10 +2,8 @@ package net.hostsharing.hsadminng.hs.office.contact;
|
|||||||
|
|
||||||
import lombok.SneakyThrows;
|
import lombok.SneakyThrows;
|
||||||
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeContactInsertResource;
|
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeContactInsertResource;
|
||||||
import net.hostsharing.hsadminng.mapper.StrictMapper;
|
|
||||||
import org.modelmapper.Converter;
|
import org.modelmapper.Converter;
|
||||||
import org.modelmapper.spi.MappingContext;
|
import org.modelmapper.spi.MappingContext;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import static net.hostsharing.hsadminng.mapper.KeyValueMap.from;
|
import static net.hostsharing.hsadminng.mapper.KeyValueMap.from;
|
||||||
@ -15,9 +13,6 @@ import static net.hostsharing.hsadminng.mapper.KeyValueMap.from;
|
|||||||
public class HsOfficeContactFromResourceConverter<E extends HsOfficeContact>
|
public class HsOfficeContactFromResourceConverter<E extends HsOfficeContact>
|
||||||
implements Converter<HsOfficeContactInsertResource, E> {
|
implements Converter<HsOfficeContactInsertResource, E> {
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private StrictMapper mapper;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@SneakyThrows
|
@SneakyThrows
|
||||||
public E convert(final MappingContext<HsOfficeContactInsertResource, E> context) {
|
public E convert(final MappingContext<HsOfficeContactInsertResource, E> context) {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
package net.hostsharing.hsadminng.hs.office.partner;
|
package net.hostsharing.hsadminng.hs.office.partner;
|
||||||
|
|
||||||
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficePartnerPatchResource;
|
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficePartnerPatchResource;
|
||||||
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationEntityPatcher;
|
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationPatcher;
|
||||||
import net.hostsharing.hsadminng.mapper.EntityPatcher;
|
import net.hostsharing.hsadminng.mapper.EntityPatcher;
|
||||||
import net.hostsharing.hsadminng.mapper.StrictMapper;
|
import net.hostsharing.hsadminng.mapper.StrictMapper;
|
||||||
|
|
||||||
@ -26,7 +26,7 @@ class HsOfficePartnerEntityPatcher implements EntityPatcher<HsOfficePartnerPatch
|
|||||||
public void apply(final HsOfficePartnerPatchResource resource) {
|
public void apply(final HsOfficePartnerPatchResource resource) {
|
||||||
|
|
||||||
if (resource.getPartnerRel() != null) {
|
if (resource.getPartnerRel() != null) {
|
||||||
new HsOfficeRelationEntityPatcher(mapper, em, entity.getPartnerRel()).apply(resource.getPartnerRel());
|
new HsOfficeRelationPatcher(mapper, em, entity.getPartnerRel()).apply(resource.getPartnerRel());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (resource.getDetails() != null) {
|
if (resource.getDetails() != null) {
|
||||||
|
@ -9,14 +9,13 @@ import net.hostsharing.hsadminng.mapper.StrictMapper;
|
|||||||
import jakarta.persistence.EntityManager;
|
import jakarta.persistence.EntityManager;
|
||||||
import jakarta.validation.ValidationException;
|
import jakarta.validation.ValidationException;
|
||||||
|
|
||||||
// FIXME: rename to HsOfficeRelationPatcher
|
public class HsOfficeRelationPatcher implements EntityPatcher<HsOfficeRelationPatchResource> {
|
||||||
public class HsOfficeRelationEntityPatcher implements EntityPatcher<HsOfficeRelationPatchResource> {
|
|
||||||
|
|
||||||
private final StrictMapper mapper;
|
private final StrictMapper mapper;
|
||||||
private final EntityManager em;
|
private final EntityManager em;
|
||||||
private final HsOfficeRelation entity;
|
private final HsOfficeRelation entity;
|
||||||
|
|
||||||
public HsOfficeRelationEntityPatcher(final StrictMapper mapper, final EntityManager em, final HsOfficeRelation entity) {
|
public HsOfficeRelationPatcher(final StrictMapper mapper, final EntityManager em, final HsOfficeRelation entity) {
|
||||||
this.mapper = mapper;
|
this.mapper = mapper;
|
||||||
this.em = em;
|
this.em = em;
|
||||||
this.entity = entity;
|
this.entity = entity;
|
@ -20,6 +20,7 @@ import org.springframework.boot.test.context.SpringBootTest;
|
|||||||
import org.springframework.data.repository.Repository;
|
import org.springframework.data.repository.Repository;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
import jakarta.annotation.PostConstruct;
|
||||||
import jakarta.persistence.Table;
|
import jakarta.persistence.Table;
|
||||||
|
|
||||||
import java.lang.annotation.Annotation;
|
import java.lang.annotation.Annotation;
|
||||||
@ -420,7 +421,7 @@ public class ArchitectureTest {
|
|||||||
if (isGeneratedSpringRepositoryMethod(item, method)) {
|
if (isGeneratedSpringRepositoryMethod(item, method)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (item.isAnnotatedWith(RestController.class) && !method.getModifiers().contains(PUBLIC)) {
|
if (!method.getModifiers().contains(PUBLIC) || method.isAnnotatedWith(PostConstruct.class)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
final var message = String.format(
|
final var message = String.format(
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package net.hostsharing.hsadminng.hs.office.partner;
|
package net.hostsharing.hsadminng.hs.office.partner;
|
||||||
|
|
||||||
import net.hostsharing.hsadminng.context.Context;
|
import net.hostsharing.hsadminng.context.Context;
|
||||||
|
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactFromResourceConverter;
|
||||||
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactRbacEntity;
|
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactRbacEntity;
|
||||||
import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonRealEntity;
|
import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonRealEntity;
|
||||||
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationRealEntity;
|
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationRealEntity;
|
||||||
@ -38,7 +39,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
|
|||||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||||
|
|
||||||
@WebMvcTest(HsOfficePartnerController.class)
|
@WebMvcTest(HsOfficePartnerController.class)
|
||||||
@Import({StrictMapper.class, DisableSecurityConfig.class})
|
@Import({ StrictMapper.class, HsOfficeContactFromResourceConverter.class, DisableSecurityConfig.class})
|
||||||
@ActiveProfiles("test")
|
@ActiveProfiles("test")
|
||||||
class HsOfficePartnerControllerRestTest {
|
class HsOfficePartnerControllerRestTest {
|
||||||
|
|
||||||
|
@ -1,234 +0,0 @@
|
|||||||
package net.hostsharing.hsadminng.hs.office.relation;
|
|
||||||
|
|
||||||
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactRealEntity;
|
|
||||||
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeContactInsertResource;
|
|
||||||
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficePersonInsertResource;
|
|
||||||
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficePersonTypeResource;
|
|
||||||
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeRelationPatchResource;
|
|
||||||
import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonRealEntity;
|
|
||||||
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;
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
import org.junit.jupiter.api.TestInstance;
|
|
||||||
import org.junit.jupiter.api.extension.ExtendWith;
|
|
||||||
import org.mockito.Mock;
|
|
||||||
import org.mockito.junit.jupiter.MockitoExtension;
|
|
||||||
import org.openapitools.jackson.nullable.JsonNullable;
|
|
||||||
|
|
||||||
import jakarta.validation.ValidationException;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.UUID;
|
|
||||||
import java.util.stream.Stream;
|
|
||||||
|
|
||||||
import static net.hostsharing.hsadminng.hs.office.person.HsOfficePersonType.LEGAL_PERSON;
|
|
||||||
import static net.hostsharing.hsadminng.hs.office.person.HsOfficePersonType.NATURAL_PERSON;
|
|
||||||
import static net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationType.PARTNER;
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
|
||||||
import static org.assertj.core.api.Assertions.catchThrowable;
|
|
||||||
import static org.assertj.core.api.Assumptions.assumeThat;
|
|
||||||
import static org.junit.jupiter.api.TestInstance.Lifecycle.PER_CLASS;
|
|
||||||
import static org.mockito.Mockito.lenient;
|
|
||||||
import static org.mockito.Mockito.times;
|
|
||||||
import static org.mockito.Mockito.verify;
|
|
||||||
|
|
||||||
@TestInstance(PER_CLASS)
|
|
||||||
@ExtendWith(MockitoExtension.class)
|
|
||||||
class HsOfficeRelationEntityPatcherUnitTest extends PatchUnitTestBase<
|
|
||||||
HsOfficeRelationPatchResource,
|
|
||||||
HsOfficeRelation
|
|
||||||
> {
|
|
||||||
|
|
||||||
private static final UUID INITIAL_RELATION_UUID = UUID.randomUUID();
|
|
||||||
private static final UUID INITIAL_ANCHOR_UUID = UUID.randomUUID();
|
|
||||||
private static final UUID INITIAL_HOLDER_UUID = UUID.randomUUID();
|
|
||||||
private static final UUID INITIAL_CONTACT_UUID = UUID.randomUUID();
|
|
||||||
|
|
||||||
private static final UUID PATCHED_HOLDER_UUID = UUID.randomUUID();
|
|
||||||
private static HsOfficePersonInsertResource HOLDER_PATCH_RESOURCE = new HsOfficePersonInsertResource() {
|
|
||||||
|
|
||||||
{
|
|
||||||
setPersonType(HsOfficePersonTypeResource.NATURAL_PERSON);
|
|
||||||
setFamilyName("Patched-Holder-Family-Name");
|
|
||||||
setGivenName("Patched-Holder-Given-Name");
|
|
||||||
}
|
|
||||||
};
|
|
||||||
private static HsOfficePersonRealEntity PATCHED_HOLDER = HsOfficePersonRealEntity.builder()
|
|
||||||
.uuid(PATCHED_HOLDER_UUID)
|
|
||||||
.personType(NATURAL_PERSON)
|
|
||||||
.familyName("Patched-Holder-Family-Name")
|
|
||||||
.givenName("Patched-Holder-Given-Name")
|
|
||||||
.build();
|
|
||||||
|
|
||||||
private static final UUID PATCHED_CONTACT_UUID = UUID.randomUUID();
|
|
||||||
private static HsOfficeContactInsertResource CONTACT_PATCH_RESOURCE = new HsOfficeContactInsertResource() {
|
|
||||||
|
|
||||||
{
|
|
||||||
setCaption("Patched-Contact-Caption");
|
|
||||||
setEmailAddresses(Map.ofEntries(
|
|
||||||
Map.entry("main", "patched@exampl.org")
|
|
||||||
));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
private static HsOfficeContactRealEntity PATCHED_CONTACT = HsOfficeContactRealEntity.builder()
|
|
||||||
.uuid(PATCHED_CONTACT_UUID)
|
|
||||||
.caption("Patched-Contact-Caption")
|
|
||||||
.emailAddresses(Map.ofEntries(
|
|
||||||
Map.entry("main", "patched@exampl.org")
|
|
||||||
))
|
|
||||||
.build();
|
|
||||||
|
|
||||||
@Mock
|
|
||||||
private EntityManagerWrapper emw;
|
|
||||||
|
|
||||||
private StrictMapper mapper = new StrictMapper(emw);
|
|
||||||
|
|
||||||
@BeforeEach
|
|
||||||
void initMocks() {
|
|
||||||
lenient().when(emw.getReference(HsOfficePersonRealEntity.class, PATCHED_HOLDER_UUID)).thenAnswer(
|
|
||||||
p -> PATCHED_HOLDER);
|
|
||||||
lenient().when(emw.getReference(HsOfficeContactRealEntity.class, PATCHED_CONTACT_UUID)).thenAnswer(
|
|
||||||
p -> PATCHED_CONTACT);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected HsOfficeRelation newInitialEntity() {
|
|
||||||
final var entity = new HsOfficeRelationRealEntity();
|
|
||||||
entity.setUuid(INITIAL_RELATION_UUID);
|
|
||||||
entity.setType(PARTNER);
|
|
||||||
entity.setAnchor(HsOfficePersonRealEntity.builder()
|
|
||||||
.uuid(INITIAL_ANCHOR_UUID)
|
|
||||||
.personType(LEGAL_PERSON)
|
|
||||||
.tradeName("Initial-Anchor-Tradename")
|
|
||||||
.build());
|
|
||||||
entity.setHolder(HsOfficePersonRealEntity.builder()
|
|
||||||
.uuid(INITIAL_HOLDER_UUID)
|
|
||||||
.personType(NATURAL_PERSON)
|
|
||||||
.familyName("Initial-Holder-Family-Name")
|
|
||||||
.givenName("Initial-Holder-Given-Name")
|
|
||||||
.build());
|
|
||||||
entity.setContact(HsOfficeContactRealEntity.builder()
|
|
||||||
.uuid(INITIAL_CONTACT_UUID)
|
|
||||||
.caption("Initial-Contact-Caption")
|
|
||||||
.build());
|
|
||||||
return entity;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected HsOfficeRelationPatchResource newPatchResource() {
|
|
||||||
return new HsOfficeRelationPatchResource();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected HsOfficeRelationEntityPatcher createPatcher(final HsOfficeRelation relation) {
|
|
||||||
return new HsOfficeRelationEntityPatcher(mapper, emw, relation);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected Stream<Property> propertyTestDescriptors() {
|
|
||||||
return Stream.of(
|
|
||||||
new JsonNullableProperty<>(
|
|
||||||
"holderUuid",
|
|
||||||
HsOfficeRelationPatchResource::setHolderUuid,
|
|
||||||
PATCHED_HOLDER_UUID,
|
|
||||||
HsOfficeRelation::setHolder,
|
|
||||||
PATCHED_HOLDER),
|
|
||||||
new SimpleProperty<>(
|
|
||||||
"holder",
|
|
||||||
HsOfficeRelationPatchResource::setHolder,
|
|
||||||
HOLDER_PATCH_RESOURCE,
|
|
||||||
HsOfficeRelation::setHolder,
|
|
||||||
withoutUuid(PATCHED_HOLDER))
|
|
||||||
.notNullable(),
|
|
||||||
|
|
||||||
new JsonNullableProperty<>(
|
|
||||||
"contactUuid",
|
|
||||||
HsOfficeRelationPatchResource::setContactUuid,
|
|
||||||
PATCHED_CONTACT_UUID,
|
|
||||||
HsOfficeRelation::setContact,
|
|
||||||
PATCHED_CONTACT),
|
|
||||||
new SimpleProperty<>(
|
|
||||||
"contact",
|
|
||||||
HsOfficeRelationPatchResource::setContact,
|
|
||||||
CONTACT_PATCH_RESOURCE,
|
|
||||||
HsOfficeRelation::setContact,
|
|
||||||
withoutUuid(PATCHED_CONTACT))
|
|
||||||
.notNullable()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void willPatchAllProperties() {
|
|
||||||
// this generic test does not work because either holder or holder.uuid can be set
|
|
||||||
assumeThat(true).isFalse();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void willThrowExceptionIfHolderAndHolderUuidAreGiven() {
|
|
||||||
// given
|
|
||||||
final var givenEntity = newInitialEntity();
|
|
||||||
final var patchResource = newPatchResource();
|
|
||||||
patchResource.setHolderUuid(JsonNullable.of(PATCHED_HOLDER_UUID));
|
|
||||||
patchResource.setHolder(HOLDER_PATCH_RESOURCE);
|
|
||||||
|
|
||||||
// when
|
|
||||||
final var exception = catchThrowable(() -> createPatcher(givenEntity).apply(patchResource));
|
|
||||||
|
|
||||||
// then
|
|
||||||
assertThat(exception).isInstanceOf(ValidationException.class)
|
|
||||||
.hasMessage("either \"holder\" or \"holder.uuid\" can be given, not both");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void willThrowExceptionIfContactAndContactUuidAreGiven() {
|
|
||||||
// given
|
|
||||||
final var givenEntity = newInitialEntity();
|
|
||||||
final var patchResource = newPatchResource();
|
|
||||||
patchResource.setContactUuid(JsonNullable.of(PATCHED_CONTACT_UUID));
|
|
||||||
patchResource.setContact(CONTACT_PATCH_RESOURCE);
|
|
||||||
|
|
||||||
// when
|
|
||||||
final var exception = catchThrowable(() -> createPatcher(givenEntity).apply(patchResource));
|
|
||||||
|
|
||||||
// then
|
|
||||||
assertThat(exception).isInstanceOf(ValidationException.class)
|
|
||||||
.hasMessage("either \"contact\" or \"contact.uuid\" can be given, not both");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void willPersistNewHolder() {
|
|
||||||
// given
|
|
||||||
final var givenEntity = newInitialEntity();
|
|
||||||
final var patchResource = newPatchResource();
|
|
||||||
patchResource.setHolder(HOLDER_PATCH_RESOURCE);
|
|
||||||
|
|
||||||
// when
|
|
||||||
createPatcher(givenEntity).apply(patchResource);
|
|
||||||
|
|
||||||
// then
|
|
||||||
verify(emw, times(1)).persist(givenEntity.getHolder());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void willPersistNewContact() {
|
|
||||||
// given
|
|
||||||
final var givenEntity = newInitialEntity();
|
|
||||||
final var patchResource = newPatchResource();
|
|
||||||
patchResource.setContact(CONTACT_PATCH_RESOURCE);
|
|
||||||
|
|
||||||
// when
|
|
||||||
createPatcher(givenEntity).apply(patchResource);
|
|
||||||
|
|
||||||
// then
|
|
||||||
verify(emw, times(1)).persist(givenEntity.getContact());
|
|
||||||
}
|
|
||||||
|
|
||||||
private HsOfficePersonRealEntity withoutUuid(final HsOfficePersonRealEntity givenWithUuid) {
|
|
||||||
return givenWithUuid.toBuilder().uuid(null).build();
|
|
||||||
}
|
|
||||||
|
|
||||||
private HsOfficeContactRealEntity withoutUuid(final HsOfficeContactRealEntity givenWithUuid) {
|
|
||||||
return givenWithUuid.toBuilder().uuid(null).build();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,26 +1,38 @@
|
|||||||
package net.hostsharing.hsadminng.hs.office.relation;
|
package net.hostsharing.hsadminng.hs.office.relation;
|
||||||
|
|
||||||
|
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactFromResourceConverter;
|
||||||
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactRealEntity;
|
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactRealEntity;
|
||||||
|
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeContactInsertResource;
|
||||||
|
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficePersonInsertResource;
|
||||||
|
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficePersonTypeResource;
|
||||||
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeRelationPatchResource;
|
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeRelationPatchResource;
|
||||||
import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonRealEntity;
|
import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonRealEntity;
|
||||||
import net.hostsharing.hsadminng.mapper.StrictMapper;
|
import net.hostsharing.hsadminng.mapper.StrictMapper;
|
||||||
import net.hostsharing.hsadminng.persistence.EntityManagerWrapper;
|
import net.hostsharing.hsadminng.persistence.EntityManagerWrapper;
|
||||||
import net.hostsharing.hsadminng.rbac.test.PatchUnitTestBase;
|
import net.hostsharing.hsadminng.rbac.test.PatchUnitTestBase;
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
import org.junit.jupiter.api.TestInstance;
|
import org.junit.jupiter.api.TestInstance;
|
||||||
import org.junit.jupiter.api.extension.ExtendWith;
|
import org.junit.jupiter.api.extension.ExtendWith;
|
||||||
import org.mockito.Mock;
|
import org.mockito.Mock;
|
||||||
import org.mockito.junit.jupiter.MockitoExtension;
|
import org.mockito.junit.jupiter.MockitoExtension;
|
||||||
|
import org.openapitools.jackson.nullable.JsonNullable;
|
||||||
|
|
||||||
|
import jakarta.validation.ValidationException;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
import static net.hostsharing.hsadminng.hs.office.person.HsOfficePersonType.LEGAL_PERSON;
|
||||||
|
import static net.hostsharing.hsadminng.hs.office.person.HsOfficePersonType.NATURAL_PERSON;
|
||||||
|
import static net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationType.PARTNER;
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
import static org.assertj.core.api.Assertions.catchThrowable;
|
||||||
|
import static org.assertj.core.api.Assumptions.assumeThat;
|
||||||
import static org.junit.jupiter.api.TestInstance.Lifecycle.PER_CLASS;
|
import static org.junit.jupiter.api.TestInstance.Lifecycle.PER_CLASS;
|
||||||
import static org.mockito.ArgumentMatchers.any;
|
|
||||||
import static org.mockito.ArgumentMatchers.eq;
|
|
||||||
import static org.mockito.Mockito.lenient;
|
import static org.mockito.Mockito.lenient;
|
||||||
|
import static org.mockito.Mockito.times;
|
||||||
// FIXME: replace with HsOfficeRelationEntityPatcherUnitTest
|
import static org.mockito.Mockito.verify;
|
||||||
|
|
||||||
@TestInstance(PER_CLASS)
|
@TestInstance(PER_CLASS)
|
||||||
@ExtendWith(MockitoExtension.class)
|
@ExtendWith(MockitoExtension.class)
|
||||||
@ -29,38 +41,84 @@ class HsOfficeRelationPatcherUnitTest extends PatchUnitTestBase<
|
|||||||
HsOfficeRelation
|
HsOfficeRelation
|
||||||
> {
|
> {
|
||||||
|
|
||||||
static final UUID INITIAL_RELATION_UUID = UUID.randomUUID();
|
private static final UUID INITIAL_RELATION_UUID = UUID.randomUUID();
|
||||||
static final UUID PATCHED_CONTACT_UUID = UUID.randomUUID();
|
private static final UUID INITIAL_ANCHOR_UUID = UUID.randomUUID();
|
||||||
|
private static final UUID INITIAL_HOLDER_UUID = UUID.randomUUID();
|
||||||
|
private static final UUID INITIAL_CONTACT_UUID = UUID.randomUUID();
|
||||||
|
|
||||||
|
private static final UUID PATCHED_HOLDER_UUID = UUID.randomUUID();
|
||||||
|
private static HsOfficePersonInsertResource HOLDER_PATCH_RESOURCE = new HsOfficePersonInsertResource();
|
||||||
|
{
|
||||||
|
{
|
||||||
|
HOLDER_PATCH_RESOURCE.setPersonType(HsOfficePersonTypeResource.NATURAL_PERSON);
|
||||||
|
HOLDER_PATCH_RESOURCE.setFamilyName("Patched-Holder-Family-Name");
|
||||||
|
HOLDER_PATCH_RESOURCE.setGivenName("Patched-Holder-Given-Name");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
private static HsOfficePersonRealEntity PATCHED_HOLDER = HsOfficePersonRealEntity.builder()
|
||||||
|
.uuid(PATCHED_HOLDER_UUID)
|
||||||
|
.personType(NATURAL_PERSON)
|
||||||
|
.familyName("Patched-Holder-Family-Name")
|
||||||
|
.givenName("Patched-Holder-Given-Name")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
private static final UUID PATCHED_CONTACT_UUID = UUID.randomUUID();
|
||||||
|
private static HsOfficeContactInsertResource CONTACT_PATCH_RESOURCE = new HsOfficeContactInsertResource();
|
||||||
|
{
|
||||||
|
{
|
||||||
|
CONTACT_PATCH_RESOURCE.setCaption("Patched-Contact-Caption");
|
||||||
|
CONTACT_PATCH_RESOURCE.setEmailAddresses(Map.ofEntries(
|
||||||
|
Map.entry("main", "patched@example.org")
|
||||||
|
));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
private static HsOfficeContactRealEntity PATCHED_CONTACT = HsOfficeContactRealEntity.builder()
|
||||||
|
.uuid(PATCHED_CONTACT_UUID)
|
||||||
|
.caption("Patched-Contact-Caption")
|
||||||
|
.emailAddresses(Map.ofEntries(
|
||||||
|
Map.entry("main", "patched@example.org")
|
||||||
|
))
|
||||||
|
.build();
|
||||||
|
|
||||||
@Mock
|
@Mock
|
||||||
EntityManagerWrapper emw;
|
private EntityManagerWrapper emw;
|
||||||
|
|
||||||
|
private StrictMapper mapper;
|
||||||
|
|
||||||
StrictMapper mapper = new StrictMapper(emw);
|
|
||||||
|
|
||||||
@BeforeEach
|
@BeforeEach
|
||||||
void initMocks() {
|
void init() {
|
||||||
lenient().when(emw.getReference(eq(HsOfficeContactRealEntity.class), any())).thenAnswer(invocation ->
|
mapper = new StrictMapper(emw); // emw is injected after the constructor got called
|
||||||
HsOfficeContactRealEntity.builder().uuid(invocation.getArgument(1)).build());
|
mapper.addConverter(
|
||||||
}
|
new HsOfficeContactFromResourceConverter<>(),
|
||||||
|
HsOfficeContactInsertResource.class, HsOfficeContactRealEntity.class);
|
||||||
|
|
||||||
final HsOfficePersonRealEntity givenInitialAnchorPerson = HsOfficePersonRealEntity.builder()
|
lenient().when(emw.getReference(HsOfficePersonRealEntity.class, PATCHED_HOLDER_UUID)).thenAnswer(
|
||||||
.uuid(UUID.randomUUID())
|
p -> PATCHED_HOLDER);
|
||||||
.build();
|
lenient().when(emw.getReference(HsOfficeContactRealEntity.class, PATCHED_CONTACT_UUID)).thenAnswer(
|
||||||
final HsOfficePersonRealEntity givenInitialHolderPerson = HsOfficePersonRealEntity.builder()
|
p -> PATCHED_CONTACT);
|
||||||
.uuid(UUID.randomUUID())
|
}
|
||||||
.build();
|
|
||||||
final HsOfficeContactRealEntity givenInitialContact = HsOfficeContactRealEntity.builder()
|
|
||||||
.uuid(UUID.randomUUID())
|
|
||||||
.build();
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected HsOfficeRelation newInitialEntity() {
|
protected HsOfficeRelation newInitialEntity() {
|
||||||
final var entity = new HsOfficeRelationRbacEntity();
|
final var entity = new HsOfficeRelationRealEntity();
|
||||||
entity.setUuid(INITIAL_RELATION_UUID);
|
entity.setUuid(INITIAL_RELATION_UUID);
|
||||||
entity.setType(HsOfficeRelationType.REPRESENTATIVE);
|
entity.setType(PARTNER);
|
||||||
entity.setAnchor(givenInitialAnchorPerson);
|
entity.setAnchor(HsOfficePersonRealEntity.builder()
|
||||||
entity.setHolder(givenInitialHolderPerson);
|
.uuid(INITIAL_ANCHOR_UUID)
|
||||||
entity.setContact(givenInitialContact);
|
.personType(LEGAL_PERSON)
|
||||||
|
.tradeName("Initial-Anchor-Tradename")
|
||||||
|
.build());
|
||||||
|
entity.setHolder(HsOfficePersonRealEntity.builder()
|
||||||
|
.uuid(INITIAL_HOLDER_UUID)
|
||||||
|
.personType(NATURAL_PERSON)
|
||||||
|
.familyName("Initial-Holder-Family-Name")
|
||||||
|
.givenName("Initial-Holder-Given-Name")
|
||||||
|
.build());
|
||||||
|
entity.setContact(HsOfficeContactRealEntity.builder()
|
||||||
|
.uuid(INITIAL_CONTACT_UUID)
|
||||||
|
.caption("Initial-Contact-Caption")
|
||||||
|
.build());
|
||||||
return entity;
|
return entity;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -70,24 +128,114 @@ class HsOfficeRelationPatcherUnitTest extends PatchUnitTestBase<
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected HsOfficeRelationEntityPatcher createPatcher(final HsOfficeRelation relation) {
|
protected HsOfficeRelationPatcher createPatcher(final HsOfficeRelation relation) {
|
||||||
return new HsOfficeRelationEntityPatcher(mapper, emw, relation);
|
return new HsOfficeRelationPatcher(mapper, emw, relation);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Stream<Property> propertyTestDescriptors() {
|
protected Stream<Property> propertyTestDescriptors() {
|
||||||
return Stream.of(
|
return Stream.of(
|
||||||
new JsonNullableProperty<>(
|
new JsonNullableProperty<>(
|
||||||
"contact",
|
"holderUuid",
|
||||||
|
HsOfficeRelationPatchResource::setHolderUuid,
|
||||||
|
PATCHED_HOLDER_UUID,
|
||||||
|
HsOfficeRelation::setHolder,
|
||||||
|
PATCHED_HOLDER),
|
||||||
|
new SimpleProperty<>(
|
||||||
|
"holder",
|
||||||
|
HsOfficeRelationPatchResource::setHolder,
|
||||||
|
HOLDER_PATCH_RESOURCE,
|
||||||
|
HsOfficeRelation::setHolder,
|
||||||
|
withoutUuid(PATCHED_HOLDER))
|
||||||
|
.notNullable(),
|
||||||
|
|
||||||
|
new JsonNullableProperty<>(
|
||||||
|
"contactUuid",
|
||||||
HsOfficeRelationPatchResource::setContactUuid,
|
HsOfficeRelationPatchResource::setContactUuid,
|
||||||
PATCHED_CONTACT_UUID,
|
PATCHED_CONTACT_UUID,
|
||||||
HsOfficeRelation::setContact,
|
HsOfficeRelation::setContact,
|
||||||
newContact(PATCHED_CONTACT_UUID))
|
PATCHED_CONTACT),
|
||||||
|
new SimpleProperty<>(
|
||||||
|
"contact",
|
||||||
|
HsOfficeRelationPatchResource::setContact,
|
||||||
|
CONTACT_PATCH_RESOURCE,
|
||||||
|
HsOfficeRelation::setContact,
|
||||||
|
withoutUuid(PATCHED_CONTACT))
|
||||||
.notNullable()
|
.notNullable()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
static HsOfficeContactRealEntity newContact(final UUID uuid) {
|
@Override
|
||||||
return HsOfficeContactRealEntity.builder().uuid(uuid).build();
|
protected void willPatchAllProperties() {
|
||||||
|
// this generic test does not work because either holder or holder.uuid can be set
|
||||||
|
assumeThat(true).isFalse();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void willThrowExceptionIfHolderAndHolderUuidAreGiven() {
|
||||||
|
// given
|
||||||
|
final var givenEntity = newInitialEntity();
|
||||||
|
final var patchResource = newPatchResource();
|
||||||
|
patchResource.setHolderUuid(JsonNullable.of(PATCHED_HOLDER_UUID));
|
||||||
|
patchResource.setHolder(HOLDER_PATCH_RESOURCE);
|
||||||
|
|
||||||
|
// when
|
||||||
|
final var exception = catchThrowable(() -> createPatcher(givenEntity).apply(patchResource));
|
||||||
|
|
||||||
|
// then
|
||||||
|
assertThat(exception).isInstanceOf(ValidationException.class)
|
||||||
|
.hasMessage("either \"holder\" or \"holder.uuid\" can be given, not both");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void willThrowExceptionIfContactAndContactUuidAreGiven() {
|
||||||
|
// given
|
||||||
|
final var givenEntity = newInitialEntity();
|
||||||
|
final var patchResource = newPatchResource();
|
||||||
|
patchResource.setContactUuid(JsonNullable.of(PATCHED_CONTACT_UUID));
|
||||||
|
patchResource.setContact(CONTACT_PATCH_RESOURCE);
|
||||||
|
|
||||||
|
// when
|
||||||
|
final var exception = catchThrowable(() -> createPatcher(givenEntity).apply(patchResource));
|
||||||
|
|
||||||
|
// then
|
||||||
|
assertThat(exception).isInstanceOf(ValidationException.class)
|
||||||
|
.hasMessage("either \"contact\" or \"contact.uuid\" can be given, not both");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void willPersistNewHolder() {
|
||||||
|
// given
|
||||||
|
final var givenEntity = newInitialEntity();
|
||||||
|
final var patchResource = newPatchResource();
|
||||||
|
patchResource.setHolder(HOLDER_PATCH_RESOURCE);
|
||||||
|
|
||||||
|
// when
|
||||||
|
createPatcher(givenEntity).apply(patchResource);
|
||||||
|
|
||||||
|
// then
|
||||||
|
verify(emw, times(1)).persist(givenEntity.getHolder());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void willPersistNewContact() {
|
||||||
|
// given
|
||||||
|
final var givenEntity = newInitialEntity();
|
||||||
|
final var patchResource = newPatchResource();
|
||||||
|
patchResource.setContact(CONTACT_PATCH_RESOURCE);
|
||||||
|
|
||||||
|
// when
|
||||||
|
createPatcher(givenEntity).apply(patchResource);
|
||||||
|
|
||||||
|
// then
|
||||||
|
verify(emw, times(1)).persist(givenEntity.getContact());
|
||||||
|
}
|
||||||
|
|
||||||
|
private HsOfficePersonRealEntity withoutUuid(final HsOfficePersonRealEntity givenWithUuid) {
|
||||||
|
return givenWithUuid.toBuilder().uuid(null).build();
|
||||||
|
}
|
||||||
|
|
||||||
|
private HsOfficeContactRealEntity withoutUuid(final HsOfficeContactRealEntity givenWithUuid) {
|
||||||
|
return givenWithUuid.toBuilder().uuid(null).build();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user