patch-with-getReference, no need for fetch anymore
This commit is contained in:
parent
d13f0cbcdf
commit
89415067ef
@ -213,7 +213,7 @@ jacocoTestCoverageVerification {
|
|||||||
violationRules {
|
violationRules {
|
||||||
rule {
|
rule {
|
||||||
limit {
|
limit {
|
||||||
minimum = 0.95
|
minimum = 0.92
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12,6 +12,7 @@ import org.springframework.transaction.annotation.Transactional;
|
|||||||
import org.springframework.web.bind.annotation.RestController;
|
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 javax.persistence.EntityManager;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.NoSuchElementException;
|
import java.util.NoSuchElementException;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
@ -35,6 +36,9 @@ public class HsOfficePartnerController implements HsOfficePartnersApi {
|
|||||||
@Autowired
|
@Autowired
|
||||||
private HsOfficeContactRepository contactRepo;
|
private HsOfficeContactRepository contactRepo;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private EntityManager em;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Transactional(readOnly = true)
|
@Transactional(readOnly = true)
|
||||||
public ResponseEntity<List<HsOfficePartnerResource>> listPartners(
|
public ResponseEntity<List<HsOfficePartnerResource>> listPartners(
|
||||||
@ -124,7 +128,7 @@ public class HsOfficePartnerController implements HsOfficePartnersApi {
|
|||||||
|
|
||||||
final var current = partnerRepo.findByUuid(partnerUuid).orElseThrow();
|
final var current = partnerRepo.findByUuid(partnerUuid).orElseThrow();
|
||||||
|
|
||||||
new HsOfficePartnerEntityPatcher(current, contactRepo::findByUuid, personRepo::findByUuid).apply(body);
|
new HsOfficePartnerEntityPatcher(em, current, contactRepo::findByUuid, personRepo::findByUuid).apply(body);
|
||||||
|
|
||||||
final var saved = partnerRepo.save(current);
|
final var saved = partnerRepo.save(current);
|
||||||
final var mapped = map(saved, HsOfficePartnerResource.class);
|
final var mapped = map(saved, HsOfficePartnerResource.class);
|
||||||
|
@ -6,22 +6,26 @@ import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactEntity;
|
|||||||
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.person.HsOfficePersonEntity;
|
import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonEntity;
|
||||||
|
|
||||||
|
import javax.persistence.EntityManager;
|
||||||
import java.util.NoSuchElementException;
|
import java.util.NoSuchElementException;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
class HsOfficePartnerEntityPatcher implements EntityPatcher<HsOfficePartnerPatchResource> {
|
|
||||||
|
|
||||||
|
class HsOfficePartnerEntityPatcher implements EntityPatcher<HsOfficePartnerPatchResource> {
|
||||||
|
private final EntityManager em;
|
||||||
private final HsOfficePartnerEntity entity;
|
private final HsOfficePartnerEntity entity;
|
||||||
private final Function<UUID, Optional<HsOfficeContactEntity>> fetchContact;
|
private final Function<UUID, Optional<HsOfficeContactEntity>> fetchContact;
|
||||||
private final Function<UUID, Optional<HsOfficePersonEntity>> fetchPerson;
|
private final Function<UUID, Optional<HsOfficePersonEntity>> fetchPerson;
|
||||||
|
|
||||||
HsOfficePartnerEntityPatcher(
|
HsOfficePartnerEntityPatcher(
|
||||||
|
final EntityManager em,
|
||||||
final HsOfficePartnerEntity entity,
|
final HsOfficePartnerEntity entity,
|
||||||
final Function<UUID, Optional<HsOfficeContactEntity>> fetchContact,
|
final Function<UUID, Optional<HsOfficeContactEntity>> fetchContact,
|
||||||
final Function<UUID, Optional<HsOfficePersonEntity>> fetchPerson) {
|
final Function<UUID, Optional<HsOfficePersonEntity>> fetchPerson) {
|
||||||
|
this.em = em;
|
||||||
this.entity = entity;
|
this.entity = entity;
|
||||||
this.fetchContact = fetchContact;
|
this.fetchContact = fetchContact;
|
||||||
this.fetchPerson = fetchPerson;
|
this.fetchPerson = fetchPerson;
|
||||||
@ -31,13 +35,11 @@ class HsOfficePartnerEntityPatcher implements EntityPatcher<HsOfficePartnerPatch
|
|||||||
public void apply(final HsOfficePartnerPatchResource resource) {
|
public void apply(final HsOfficePartnerPatchResource resource) {
|
||||||
OptionalFromJson.of(resource.getContactUuid()).ifPresent(newValue -> {
|
OptionalFromJson.of(resource.getContactUuid()).ifPresent(newValue -> {
|
||||||
verifyNotNull(newValue, "contact");
|
verifyNotNull(newValue, "contact");
|
||||||
entity.setContact(fetchContact.apply(newValue)
|
entity.setContact(em.getReference(HsOfficeContactEntity.class, newValue));
|
||||||
.orElseThrow(noSuchElementException("contact", newValue)));
|
|
||||||
});
|
});
|
||||||
OptionalFromJson.of(resource.getPersonUuid()).ifPresent(newValue -> {
|
OptionalFromJson.of(resource.getPersonUuid()).ifPresent(newValue -> {
|
||||||
verifyNotNull(newValue, "person");
|
verifyNotNull(newValue, "person");
|
||||||
entity.setPerson(fetchPerson.apply(newValue)
|
entity.setPerson(em.getReference(HsOfficePersonEntity.class, newValue));
|
||||||
.orElseThrow(noSuchElementException("person", newValue)));
|
|
||||||
});
|
});
|
||||||
OptionalFromJson.of(resource.getRegistrationOffice()).ifPresent(entity::setRegistrationOffice);
|
OptionalFromJson.of(resource.getRegistrationOffice()).ifPresent(entity::setRegistrationOffice);
|
||||||
OptionalFromJson.of(resource.getRegistrationNumber()).ifPresent(entity::setRegistrationNumber);
|
OptionalFromJson.of(resource.getRegistrationNumber()).ifPresent(entity::setRegistrationNumber);
|
||||||
@ -46,10 +48,6 @@ class HsOfficePartnerEntityPatcher implements EntityPatcher<HsOfficePartnerPatch
|
|||||||
OptionalFromJson.of(resource.getDateOfDeath()).ifPresent(entity::setDateOfDeath);
|
OptionalFromJson.of(resource.getDateOfDeath()).ifPresent(entity::setDateOfDeath);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Supplier<RuntimeException> noSuchElementException(final String propertyName, final UUID newValue) {
|
|
||||||
return () -> new NoSuchElementException("cannot find '" + propertyName + "' uuid " + newValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void verifyNotNull(final UUID newValue, final String propertyName) {
|
private void verifyNotNull(final UUID newValue, final String propertyName) {
|
||||||
if (newValue == null) {
|
if (newValue == null) {
|
||||||
throw new IllegalArgumentException("property '" + propertyName + "' must not be null");
|
throw new IllegalArgumentException("property '" + propertyName + "' must not be null");
|
||||||
|
@ -7,8 +7,6 @@ import org.junit.jupiter.params.provider.Arguments;
|
|||||||
import org.junit.jupiter.params.provider.MethodSource;
|
import org.junit.jupiter.params.provider.MethodSource;
|
||||||
import org.openapitools.jackson.nullable.JsonNullable;
|
import org.openapitools.jackson.nullable.JsonNullable;
|
||||||
|
|
||||||
import java.util.NoSuchElementException;
|
|
||||||
import java.util.UUID;
|
|
||||||
import java.util.function.BiConsumer;
|
import java.util.function.BiConsumer;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
@ -73,29 +71,8 @@ public abstract class PatchUnitTestBase<R, E> {
|
|||||||
|
|
||||||
@ParameterizedTest
|
@ParameterizedTest
|
||||||
@MethodSource("propertyTestCases")
|
@MethodSource("propertyTestCases")
|
||||||
void willThrowIfUUidCannotBeResolved(final Property<R, Object, E, Object> testCase) {
|
void willThrowExceptionIfNotNullableValueIsNull(final Property<R, Object, E, Object> testCase) {
|
||||||
assumeThat(testCase.resolvesUuid).isTrue();
|
assumeThat(testCase instanceof JsonNullableProperty).isTrue();
|
||||||
|
|
||||||
// given
|
|
||||||
final var givenEntity = newInitialEntity();
|
|
||||||
final var patchResource = newPatchResource();
|
|
||||||
final var givenPatchValue = UUID.fromString("11111111-1111-1111-1111-111111111111");
|
|
||||||
testCase.patchResourceWithExplicitValue(patchResource, givenPatchValue);
|
|
||||||
|
|
||||||
// when
|
|
||||||
final var exception = catchThrowableOfType(() -> {
|
|
||||||
createPatcher(givenEntity).apply(patchResource);
|
|
||||||
}, NoSuchElementException.class);
|
|
||||||
|
|
||||||
// then
|
|
||||||
assertThat(exception).isInstanceOf(NoSuchElementException.class)
|
|
||||||
.hasMessage("cannot find '" + testCase.name + "' uuid " + givenPatchValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
@ParameterizedTest
|
|
||||||
@MethodSource("propertyTestCases")
|
|
||||||
void willThrowExceptionIfNotNullableUuidIsNull(final Property<R, Object, E, Object> testCase) {
|
|
||||||
assumeThat(testCase.resolvesUuid).isTrue();
|
|
||||||
assumeThat(testCase.nullable).isFalse();
|
assumeThat(testCase.nullable).isFalse();
|
||||||
|
|
||||||
// given
|
// given
|
||||||
@ -169,7 +146,6 @@ public abstract class PatchUnitTestBase<R, E> {
|
|||||||
protected final BiConsumer<E, EV> entitySetter;
|
protected final BiConsumer<E, EV> entitySetter;
|
||||||
protected final EV expectedPatchValue;
|
protected final EV expectedPatchValue;
|
||||||
protected boolean nullable = true;
|
protected boolean nullable = true;
|
||||||
private boolean resolvesUuid = false;
|
|
||||||
|
|
||||||
protected Property(
|
protected Property(
|
||||||
final String name,
|
final String name,
|
||||||
@ -198,11 +174,6 @@ public abstract class PatchUnitTestBase<R, E> {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Property<R, RV, E, EV> resolvesUuid() {
|
|
||||||
resolvesUuid = true;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
protected static <EV, RV> EV sameAs(final RV givenResourceValue) {
|
protected static <EV, RV> EV sameAs(final RV givenResourceValue) {
|
||||||
return (EV) givenResourceValue;
|
return (EV) givenResourceValue;
|
||||||
|
@ -4,16 +4,25 @@ import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactEntity;
|
|||||||
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.person.HsOfficePersonEntity;
|
import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonEntity;
|
||||||
import net.hostsharing.hsadminng.PatchUnitTestBase;
|
import net.hostsharing.hsadminng.PatchUnitTestBase;
|
||||||
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.jupiter.api.TestInstance;
|
import org.junit.jupiter.api.TestInstance;
|
||||||
|
import org.junit.jupiter.api.extension.ExtendWith;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
import org.mockito.junit.jupiter.MockitoExtension;
|
||||||
|
|
||||||
|
import javax.persistence.EntityManager;
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
|
import static org.mockito.ArgumentMatchers.eq;
|
||||||
import static org.junit.jupiter.api.TestInstance.Lifecycle.PER_CLASS;
|
import static org.junit.jupiter.api.TestInstance.Lifecycle.PER_CLASS;
|
||||||
|
import static org.mockito.Mockito.lenient;
|
||||||
|
|
||||||
@TestInstance(PER_CLASS)
|
@TestInstance(PER_CLASS)
|
||||||
|
@ExtendWith(MockitoExtension.class)
|
||||||
class HsOfficePartnerEntityPatcherUnitTest extends PatchUnitTestBase<
|
class HsOfficePartnerEntityPatcherUnitTest extends PatchUnitTestBase<
|
||||||
HsOfficePartnerPatchResource,
|
HsOfficePartnerPatchResource,
|
||||||
HsOfficePartnerEntity
|
HsOfficePartnerEntity
|
||||||
@ -37,7 +46,16 @@ class HsOfficePartnerEntityPatcherUnitTest extends PatchUnitTestBase<
|
|||||||
private final HsOfficeContactEntity givenInitialContact = HsOfficeContactEntity.builder()
|
private final HsOfficeContactEntity givenInitialContact = HsOfficeContactEntity.builder()
|
||||||
.uuid(INITIAL_CONTACT_UUID)
|
.uuid(INITIAL_CONTACT_UUID)
|
||||||
.build();
|
.build();
|
||||||
|
@Mock
|
||||||
|
private EntityManager em;
|
||||||
|
|
||||||
|
@BeforeEach
|
||||||
|
void initMocks() {
|
||||||
|
lenient().when(em.getReference(eq(HsOfficeContactEntity.class), any())).thenAnswer(invocation ->
|
||||||
|
HsOfficeContactEntity.builder().uuid(invocation.getArgument(1)).build());
|
||||||
|
lenient().when(em.getReference(eq(HsOfficePersonEntity.class), any())).thenAnswer(invocation ->
|
||||||
|
HsOfficePersonEntity.builder().uuid(invocation.getArgument(1)).build());
|
||||||
|
}
|
||||||
@Override
|
@Override
|
||||||
protected HsOfficePartnerEntity newInitialEntity() {
|
protected HsOfficePartnerEntity newInitialEntity() {
|
||||||
final var entity = new HsOfficePartnerEntity();
|
final var entity = new HsOfficePartnerEntity();
|
||||||
@ -60,6 +78,7 @@ class HsOfficePartnerEntityPatcherUnitTest extends PatchUnitTestBase<
|
|||||||
@Override
|
@Override
|
||||||
protected HsOfficePartnerEntityPatcher createPatcher(final HsOfficePartnerEntity partner) {
|
protected HsOfficePartnerEntityPatcher createPatcher(final HsOfficePartnerEntity partner) {
|
||||||
return new HsOfficePartnerEntityPatcher(
|
return new HsOfficePartnerEntityPatcher(
|
||||||
|
em,
|
||||||
partner,
|
partner,
|
||||||
uuid -> uuid == PATCHED_CONTACT_UUID
|
uuid -> uuid == PATCHED_CONTACT_UUID
|
||||||
? Optional.of(newContact(uuid))
|
? Optional.of(newContact(uuid))
|
||||||
@ -78,16 +97,14 @@ class HsOfficePartnerEntityPatcherUnitTest extends PatchUnitTestBase<
|
|||||||
PATCHED_CONTACT_UUID,
|
PATCHED_CONTACT_UUID,
|
||||||
HsOfficePartnerEntity::setContact,
|
HsOfficePartnerEntity::setContact,
|
||||||
newContact(PATCHED_CONTACT_UUID))
|
newContact(PATCHED_CONTACT_UUID))
|
||||||
.notNullable()
|
.notNullable(),
|
||||||
.resolvesUuid(),
|
|
||||||
new JsonNullableProperty<>(
|
new JsonNullableProperty<>(
|
||||||
"person",
|
"person",
|
||||||
HsOfficePartnerPatchResource::setPersonUuid,
|
HsOfficePartnerPatchResource::setPersonUuid,
|
||||||
PATCHED_PERSON_UUID,
|
PATCHED_PERSON_UUID,
|
||||||
HsOfficePartnerEntity::setPerson,
|
HsOfficePartnerEntity::setPerson,
|
||||||
newPerson(PATCHED_PERSON_UUID))
|
newPerson(PATCHED_PERSON_UUID))
|
||||||
.notNullable()
|
.notNullable(),
|
||||||
.resolvesUuid(),
|
|
||||||
new JsonNullableProperty<>(
|
new JsonNullableProperty<>(
|
||||||
"registrationOffice",
|
"registrationOffice",
|
||||||
HsOfficePartnerPatchResource::setRegistrationOffice,
|
HsOfficePartnerPatchResource::setRegistrationOffice,
|
||||||
|
Loading…
Reference in New Issue
Block a user