refactor HsOfficePersonEntityPatchUnitTest to PatchUnitTestBase
This commit is contained in:
parent
3e6da45302
commit
b431a6653d
@ -1,4 +1,4 @@
|
|||||||
package net.hostsharing.hsadminng.hs.office.partner;
|
package net.hostsharing.hsadminng;
|
||||||
|
|
||||||
public interface EntityPatch<R> {
|
public interface EntityPatch<R> {
|
||||||
|
|
@ -1,5 +1,6 @@
|
|||||||
package net.hostsharing.hsadminng.hs.office.partner;
|
package net.hostsharing.hsadminng.hs.office.partner;
|
||||||
|
|
||||||
|
import net.hostsharing.hsadminng.EntityPatch;
|
||||||
import net.hostsharing.hsadminng.OptionalFromJson;
|
import net.hostsharing.hsadminng.OptionalFromJson;
|
||||||
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactEntity;
|
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;
|
||||||
|
@ -3,10 +3,11 @@ package net.hostsharing.hsadminng.hs.office.person;
|
|||||||
import net.hostsharing.hsadminng.OptionalFromJson;
|
import net.hostsharing.hsadminng.OptionalFromJson;
|
||||||
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficePersonPatchResource;
|
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficePersonPatchResource;
|
||||||
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficePersonTypeResource;
|
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficePersonTypeResource;
|
||||||
|
import net.hostsharing.hsadminng.EntityPatch;
|
||||||
|
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
class HsOfficePersonEntityPatch {
|
class HsOfficePersonEntityPatch implements EntityPatch<HsOfficePersonPatchResource> {
|
||||||
|
|
||||||
private final HsOfficePersonEntity entity;
|
private final HsOfficePersonEntity entity;
|
||||||
|
|
||||||
@ -14,7 +15,8 @@ class HsOfficePersonEntityPatch {
|
|||||||
this.entity = entity;
|
this.entity = entity;
|
||||||
}
|
}
|
||||||
|
|
||||||
void apply(final HsOfficePersonPatchResource resource) {
|
@Override
|
||||||
|
public void apply(final HsOfficePersonPatchResource resource) {
|
||||||
Optional.ofNullable(resource.getPersonType())
|
Optional.ofNullable(resource.getPersonType())
|
||||||
.map(HsOfficePersonTypeResource::getValue)
|
.map(HsOfficePersonTypeResource::getValue)
|
||||||
.map(HsOfficePersonType::valueOf)
|
.map(HsOfficePersonType::valueOf)
|
||||||
|
312
src/test/java/net/hostsharing/hsadminng/PatchUnitTestBase.java
Normal file
312
src/test/java/net/hostsharing/hsadminng/PatchUnitTestBase.java
Normal file
@ -0,0 +1,312 @@
|
|||||||
|
package net.hostsharing.hsadminng;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Named;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.params.ParameterizedTest;
|
||||||
|
import org.junit.jupiter.params.provider.Arguments;
|
||||||
|
import org.junit.jupiter.params.provider.MethodSource;
|
||||||
|
import org.openapitools.jackson.nullable.JsonNullable;
|
||||||
|
|
||||||
|
import java.util.NoSuchElementException;
|
||||||
|
import java.util.UUID;
|
||||||
|
import java.util.function.BiConsumer;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
import static org.assertj.core.api.Assertions.catchThrowableOfType;
|
||||||
|
import static org.assertj.core.api.Assumptions.assumeThat;
|
||||||
|
|
||||||
|
public abstract class PatchUnitTestBase<R, E> {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void willPatchNoProperty() {
|
||||||
|
// given
|
||||||
|
final var givenEntity = newInitialEntity();
|
||||||
|
final var patchResource = newPatchResource();
|
||||||
|
|
||||||
|
// when
|
||||||
|
createPatcher(givenEntity).apply(patchResource);
|
||||||
|
|
||||||
|
// then
|
||||||
|
final var expectedEntity = newInitialEntity();
|
||||||
|
assertThat(givenEntity).usingRecursiveComparison().isEqualTo(expectedEntity);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
void willPatchAllProperties() {
|
||||||
|
// given
|
||||||
|
final var givenEntity = newInitialEntity();
|
||||||
|
final var patchResource = newPatchResource();
|
||||||
|
propertyTestDescriptors().forEach(testCase ->
|
||||||
|
testCase.patchResource(patchResource)
|
||||||
|
);
|
||||||
|
|
||||||
|
// when
|
||||||
|
createPatcher(givenEntity).apply(patchResource);
|
||||||
|
|
||||||
|
// then
|
||||||
|
final var expectedEntity = newInitialEntity();
|
||||||
|
propertyTestDescriptors().forEach(testCase ->
|
||||||
|
testCase.updateEntity(expectedEntity)
|
||||||
|
);
|
||||||
|
assertThat(givenEntity).usingRecursiveComparison().isEqualTo(expectedEntity);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ParameterizedTest
|
||||||
|
@MethodSource("propertyTestCases")
|
||||||
|
void willPatchOnlyGivenProperty(final Property<R, Object, E, Object> testCase) {
|
||||||
|
|
||||||
|
// given
|
||||||
|
final var givenEntity = newInitialEntity();
|
||||||
|
final var patchResource = newPatchResource();
|
||||||
|
testCase.patchResource(patchResource);
|
||||||
|
|
||||||
|
// when
|
||||||
|
createPatcher(givenEntity).apply(patchResource);
|
||||||
|
|
||||||
|
// then
|
||||||
|
final var expectedEntity = newInitialEntity();
|
||||||
|
testCase.updateEntity(expectedEntity);
|
||||||
|
assertThat(givenEntity).usingRecursiveComparison().isEqualTo(expectedEntity);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ParameterizedTest
|
||||||
|
@MethodSource("propertyTestCases")
|
||||||
|
void willThrowIfUUidCannotBeResolved(final Property<R, Object, E, Object> testCase) {
|
||||||
|
assumeThat(testCase.resolvesUuid).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();
|
||||||
|
|
||||||
|
// given
|
||||||
|
final var givenEntity = newInitialEntity();
|
||||||
|
final var patchResource = newPatchResource();
|
||||||
|
testCase.patchResourceToNullValue(patchResource);
|
||||||
|
|
||||||
|
// when
|
||||||
|
final var actualException = catchThrowableOfType(
|
||||||
|
() -> createPatcher(givenEntity).apply(patchResource),
|
||||||
|
IllegalArgumentException.class);
|
||||||
|
|
||||||
|
// then
|
||||||
|
assertThat(actualException).hasMessage("property '" + testCase.name + "' must not be null");
|
||||||
|
assertThat(givenEntity).usingRecursiveComparison().isEqualTo(newInitialEntity());
|
||||||
|
}
|
||||||
|
|
||||||
|
@ParameterizedTest
|
||||||
|
@MethodSource("propertyTestCases")
|
||||||
|
void willPatchOnlyGivenPropertyToNull(final Property<R, Object, E, Object> testCase) {
|
||||||
|
assumeThat(testCase.nullable).isTrue();
|
||||||
|
|
||||||
|
// given
|
||||||
|
final var givenEntity = newInitialEntity();
|
||||||
|
final var patchResource = newPatchResource();
|
||||||
|
testCase.patchResourceToNullValue(patchResource);
|
||||||
|
|
||||||
|
// when
|
||||||
|
createPatcher(givenEntity).apply(patchResource);
|
||||||
|
|
||||||
|
// then
|
||||||
|
final var expectedEntity = newInitialEntity();
|
||||||
|
testCase.entitySetter.accept(expectedEntity, null);
|
||||||
|
assertThat(givenEntity).usingRecursiveComparison().isEqualTo(expectedEntity);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ParameterizedTest
|
||||||
|
@MethodSource("propertyTestCases")
|
||||||
|
void willNotPatchIfGivenPropertyNotGiven(final Property<R, Object, E, Object> testCase) {
|
||||||
|
|
||||||
|
// given
|
||||||
|
final var givenEntity = newInitialEntity();
|
||||||
|
final var patchResource = newPatchResource();
|
||||||
|
testCase.patchResourceToNotGiven(patchResource);
|
||||||
|
|
||||||
|
// when
|
||||||
|
createPatcher(givenEntity).apply(patchResource);
|
||||||
|
|
||||||
|
// then
|
||||||
|
final var expectedEntity = newInitialEntity();
|
||||||
|
assertThat(givenEntity).usingRecursiveComparison().isEqualTo(expectedEntity);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract E newInitialEntity();
|
||||||
|
|
||||||
|
protected abstract R newPatchResource();
|
||||||
|
|
||||||
|
protected abstract EntityPatch<R> createPatcher(final E entity);
|
||||||
|
|
||||||
|
@SuppressWarnings("rawtypes")
|
||||||
|
protected abstract Stream<Property> propertyTestDescriptors();
|
||||||
|
|
||||||
|
private Stream<Arguments> propertyTestCases() {
|
||||||
|
return propertyTestDescriptors()
|
||||||
|
.map(tc -> Arguments.of(Named.of(tc.name, tc)));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static abstract class Property<R, RV, E, EV> {
|
||||||
|
|
||||||
|
protected final String name;
|
||||||
|
protected final BiConsumer<E, EV> entitySetter;
|
||||||
|
protected final EV expectedPatchValue;
|
||||||
|
protected boolean nullable = true;
|
||||||
|
private boolean resolvesUuid = false;
|
||||||
|
|
||||||
|
protected Property(
|
||||||
|
final String name,
|
||||||
|
final BiConsumer<E, EV> entitySetter,
|
||||||
|
final EV givenPatchValue) {
|
||||||
|
this.name = name;
|
||||||
|
|
||||||
|
this.entitySetter = entitySetter;
|
||||||
|
this.expectedPatchValue = givenPatchValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract void patchResource(R patchResource);
|
||||||
|
|
||||||
|
protected abstract void patchResourceToNullValue(R patchResource);
|
||||||
|
|
||||||
|
protected abstract void patchResourceToNotGiven(R patchResource);
|
||||||
|
|
||||||
|
protected abstract void patchResourceWithExplicitValue(final R patchResource, final RV explicitPatchValue);
|
||||||
|
|
||||||
|
void updateEntity(final E expectedEntity) {
|
||||||
|
entitySetter.accept(expectedEntity, expectedPatchValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Property<R, RV, E, EV> notNullable() {
|
||||||
|
nullable = false;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Property<R, RV, E, EV> resolvesUuid() {
|
||||||
|
resolvesUuid = true;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
protected static <EV, RV> EV sameAs(final RV givenResourceValue) {
|
||||||
|
return (EV) givenResourceValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static class SimpleProperty<R, RV, E, EV> extends Property<R, RV, E, EV> {
|
||||||
|
|
||||||
|
public final RV givenPatchValue;
|
||||||
|
private final BiConsumer<R, RV> resourceSetter;
|
||||||
|
|
||||||
|
public SimpleProperty(
|
||||||
|
final String name,
|
||||||
|
final BiConsumer<R, RV> resourceSetter,
|
||||||
|
final RV givenPatchValue,
|
||||||
|
final BiConsumer<E, EV> entitySetter
|
||||||
|
) {
|
||||||
|
super(name, entitySetter, sameAs(givenPatchValue));
|
||||||
|
this.resourceSetter = resourceSetter;
|
||||||
|
this.givenPatchValue = givenPatchValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SimpleProperty(
|
||||||
|
final String name,
|
||||||
|
final BiConsumer<R, RV> resourceSetter,
|
||||||
|
final RV givenPatchValue,
|
||||||
|
final BiConsumer<E, EV> entitySetter,
|
||||||
|
final EV expectedPatchValue
|
||||||
|
) {
|
||||||
|
super(name, entitySetter, expectedPatchValue);
|
||||||
|
this.resourceSetter = resourceSetter;
|
||||||
|
this.givenPatchValue = givenPatchValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void patchResource(final R patchResource) {
|
||||||
|
resourceSetter.accept(patchResource, givenPatchValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void patchResourceToNullValue(final R patchResource) {
|
||||||
|
assertThat(nullable).isTrue(); // null can mean "not given" or "null value", not both
|
||||||
|
resourceSetter.accept(patchResource, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void patchResourceToNotGiven(final R patchResource) {
|
||||||
|
assertThat(nullable).isFalse(); // null can mean "not given" or "null value", not both
|
||||||
|
resourceSetter.accept(patchResource, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void patchResourceWithExplicitValue(final R patchResource, final RV explicitPatchValue) {
|
||||||
|
resourceSetter.accept(patchResource, explicitPatchValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static class JsonNullableProperty<R, RV, E, EV> extends Property<R, RV, E, EV> {
|
||||||
|
|
||||||
|
private final BiConsumer<R, JsonNullable<RV>> resourceSetter;
|
||||||
|
public final RV givenPatchValue;
|
||||||
|
|
||||||
|
public JsonNullableProperty(
|
||||||
|
final String name,
|
||||||
|
final BiConsumer<R, JsonNullable<RV>> resourceSetter,
|
||||||
|
final RV givenPatchValue,
|
||||||
|
final BiConsumer<E, EV> entitySetter
|
||||||
|
) {
|
||||||
|
super(name, entitySetter, sameAs(givenPatchValue));
|
||||||
|
this.resourceSetter = resourceSetter;
|
||||||
|
this.givenPatchValue = givenPatchValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public JsonNullableProperty(
|
||||||
|
final String name,
|
||||||
|
final BiConsumer<R, JsonNullable<RV>> resourceSetter,
|
||||||
|
final RV givenPatchValue,
|
||||||
|
final BiConsumer<E, EV> entitySetter,
|
||||||
|
final EV expectedPatchValue
|
||||||
|
) {
|
||||||
|
super(name, entitySetter, expectedPatchValue);
|
||||||
|
this.resourceSetter = resourceSetter;
|
||||||
|
this.givenPatchValue = givenPatchValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void patchResource(final R patchResource) {
|
||||||
|
resourceSetter.accept(patchResource, JsonNullable.of(givenPatchValue));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void patchResourceToNullValue(final R patchResource) {
|
||||||
|
resourceSetter.accept(patchResource, JsonNullable.of(null));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void patchResourceToNotGiven(final R patchResource) {
|
||||||
|
resourceSetter.accept(patchResource, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void patchResourceWithExplicitValue(final R patchResource, final RV explicitPatchValue) {
|
||||||
|
resourceSetter.accept(patchResource, JsonNullable.of(explicitPatchValue));
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -3,6 +3,7 @@ package net.hostsharing.hsadminng.hs.office.partner;
|
|||||||
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactEntity;
|
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 org.junit.jupiter.api.TestInstance;
|
import org.junit.jupiter.api.TestInstance;
|
||||||
|
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
@ -38,26 +39,26 @@ class HsOfficePartnerEntityPatchUnitTest extends PatchUnitTestBase<
|
|||||||
.build();
|
.build();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
HsOfficePartnerEntity newInitialEntity() {
|
protected HsOfficePartnerEntity newInitialEntity() {
|
||||||
final var p = new HsOfficePartnerEntity();
|
final var entity = new HsOfficePartnerEntity();
|
||||||
p.setUuid(INITIAL_PARTNER_UUID);
|
entity.setUuid(INITIAL_PARTNER_UUID);
|
||||||
p.setPerson(givenInitialPerson);
|
entity.setPerson(givenInitialPerson);
|
||||||
p.setContact(givenInitialContact);
|
entity.setContact(givenInitialContact);
|
||||||
p.setRegistrationOffice("initial Reg-Office");
|
entity.setRegistrationOffice("initial Reg-Office");
|
||||||
p.setRegistrationNumber("initial Reg-Number");
|
entity.setRegistrationNumber("initial Reg-Number");
|
||||||
p.setBirthday(INITIAL_BIRTHDAY);
|
entity.setBirthday(INITIAL_BIRTHDAY);
|
||||||
p.setBirthName("initial birth name");
|
entity.setBirthName("initial birth name");
|
||||||
p.setDateOfDeath(INITIAL_DAY_OF_DEATH);
|
entity.setDateOfDeath(INITIAL_DAY_OF_DEATH);
|
||||||
return p;
|
return entity;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
HsOfficePartnerPatchResource newPatchResource() {
|
protected HsOfficePartnerPatchResource newPatchResource() {
|
||||||
return new HsOfficePartnerPatchResource();
|
return new HsOfficePartnerPatchResource();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
HsOfficePartnerEntityPatch createPatcher(final HsOfficePartnerEntity partner) {
|
protected HsOfficePartnerEntityPatch createPatcher(final HsOfficePartnerEntity partner) {
|
||||||
return new HsOfficePartnerEntityPatch(
|
return new HsOfficePartnerEntityPatch(
|
||||||
partner,
|
partner,
|
||||||
uuid -> uuid == PATCHED_CONTACT_UUID
|
uuid -> uuid == PATCHED_CONTACT_UUID
|
||||||
@ -69,9 +70,9 @@ class HsOfficePartnerEntityPatchUnitTest extends PatchUnitTestBase<
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
Stream<TestCase> testCases() {
|
protected Stream<Property> propertyTestDescriptors() {
|
||||||
return Stream.of(
|
return Stream.of(
|
||||||
new TestCase(
|
new JsonNullableProperty<>(
|
||||||
"contact",
|
"contact",
|
||||||
HsOfficePartnerPatchResource::setContactUuid,
|
HsOfficePartnerPatchResource::setContactUuid,
|
||||||
PATCHED_CONTACT_UUID,
|
PATCHED_CONTACT_UUID,
|
||||||
@ -79,7 +80,7 @@ class HsOfficePartnerEntityPatchUnitTest extends PatchUnitTestBase<
|
|||||||
newContact(PATCHED_CONTACT_UUID))
|
newContact(PATCHED_CONTACT_UUID))
|
||||||
.notNullable()
|
.notNullable()
|
||||||
.resolvesUuid(),
|
.resolvesUuid(),
|
||||||
new TestCase(
|
new JsonNullableProperty<>(
|
||||||
"person",
|
"person",
|
||||||
HsOfficePartnerPatchResource::setPersonUuid,
|
HsOfficePartnerPatchResource::setPersonUuid,
|
||||||
PATCHED_PERSON_UUID,
|
PATCHED_PERSON_UUID,
|
||||||
@ -87,17 +88,17 @@ class HsOfficePartnerEntityPatchUnitTest extends PatchUnitTestBase<
|
|||||||
newPerson(PATCHED_PERSON_UUID))
|
newPerson(PATCHED_PERSON_UUID))
|
||||||
.notNullable()
|
.notNullable()
|
||||||
.resolvesUuid(),
|
.resolvesUuid(),
|
||||||
new TestCase(
|
new JsonNullableProperty<>(
|
||||||
"registrationOffice",
|
"registrationOffice",
|
||||||
HsOfficePartnerPatchResource::setRegistrationOffice,
|
HsOfficePartnerPatchResource::setRegistrationOffice,
|
||||||
"patched Reg-Office",
|
"patched Reg-Office",
|
||||||
HsOfficePartnerEntity::setRegistrationOffice),
|
HsOfficePartnerEntity::setRegistrationOffice),
|
||||||
new TestCase(
|
new JsonNullableProperty<>(
|
||||||
"birthday",
|
"birthday",
|
||||||
HsOfficePartnerPatchResource::setBirthday,
|
HsOfficePartnerPatchResource::setBirthday,
|
||||||
PATCHED_BIRTHDAY,
|
PATCHED_BIRTHDAY,
|
||||||
HsOfficePartnerEntity::setBirthday),
|
HsOfficePartnerEntity::setBirthday),
|
||||||
new TestCase(
|
new JsonNullableProperty<>(
|
||||||
"dayOfDeath",
|
"dayOfDeath",
|
||||||
HsOfficePartnerPatchResource::setDateOfDeath,
|
HsOfficePartnerPatchResource::setDateOfDeath,
|
||||||
PATCHED_DATE_OF_DEATH,
|
PATCHED_DATE_OF_DEATH,
|
||||||
|
@ -1,210 +0,0 @@
|
|||||||
package net.hostsharing.hsadminng.hs.office.partner;
|
|
||||||
|
|
||||||
import org.junit.jupiter.api.Named;
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
import org.junit.jupiter.params.ParameterizedTest;
|
|
||||||
import org.junit.jupiter.params.provider.Arguments;
|
|
||||||
import org.junit.jupiter.params.provider.MethodSource;
|
|
||||||
import org.openapitools.jackson.nullable.JsonNullable;
|
|
||||||
|
|
||||||
import java.util.NoSuchElementException;
|
|
||||||
import java.util.UUID;
|
|
||||||
import java.util.function.BiConsumer;
|
|
||||||
import java.util.stream.Stream;
|
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
|
||||||
import static org.assertj.core.api.Assertions.catchThrowableOfType;
|
|
||||||
import static org.assertj.core.api.Assumptions.assumeThat;
|
|
||||||
|
|
||||||
public abstract class PatchUnitTestBase<R, E> {
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void willPatchNoProperty() {
|
|
||||||
// given
|
|
||||||
final var givenEntity = newInitialEntity();
|
|
||||||
final var patchResource = newPatchResource();
|
|
||||||
|
|
||||||
// when
|
|
||||||
createPatcher(givenEntity).apply(patchResource);
|
|
||||||
|
|
||||||
// then
|
|
||||||
final var expectedEntity = newInitialEntity();
|
|
||||||
assertThat(givenEntity).usingRecursiveComparison().isEqualTo(expectedEntity);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void willPatchAllProperties() {
|
|
||||||
// given
|
|
||||||
final var givenEntity = newInitialEntity();
|
|
||||||
final var patchResource = newPatchResource();
|
|
||||||
testCases().forEach(testCase ->
|
|
||||||
testCase.resourceSetter.accept(patchResource, JsonNullable.of(testCase.givenPatchedValue))
|
|
||||||
);
|
|
||||||
|
|
||||||
// when
|
|
||||||
createPatcher(givenEntity).apply(patchResource);
|
|
||||||
|
|
||||||
// then
|
|
||||||
final var expectedEntity = newInitialEntity();
|
|
||||||
testCases().forEach(testCase ->
|
|
||||||
testCase.entitySetter.accept(expectedEntity, testCase.expectedPatchValue)
|
|
||||||
);
|
|
||||||
assertThat(givenEntity).usingRecursiveComparison().isEqualTo(expectedEntity);
|
|
||||||
}
|
|
||||||
|
|
||||||
@ParameterizedTest
|
|
||||||
@MethodSource("testCaseArguments")
|
|
||||||
void willPatchOnlyGivenProperty(final TestCase testCase) {
|
|
||||||
|
|
||||||
// given
|
|
||||||
final var givenEntity = newInitialEntity();
|
|
||||||
final var patchResource = newPatchResource();
|
|
||||||
testCase.resourceSetter.accept(patchResource, JsonNullable.of(testCase.givenPatchedValue));
|
|
||||||
|
|
||||||
// when
|
|
||||||
createPatcher(givenEntity).apply(patchResource);
|
|
||||||
|
|
||||||
// then
|
|
||||||
final var expectedEntity = newInitialEntity();
|
|
||||||
testCase.entitySetter.accept(expectedEntity, testCase.expectedPatchValue);
|
|
||||||
assertThat(givenEntity).usingRecursiveComparison().isEqualTo(expectedEntity);
|
|
||||||
}
|
|
||||||
|
|
||||||
@ParameterizedTest
|
|
||||||
@MethodSource("testCaseArguments")
|
|
||||||
void willThrowIfUUidCannotBeResolved(final TestCase testCase) {
|
|
||||||
assumeThat(testCase.resolvesUuid).isTrue();
|
|
||||||
|
|
||||||
// given
|
|
||||||
final var givenEntity = newInitialEntity();
|
|
||||||
final var patchResource = newPatchResource();
|
|
||||||
final var givenPatchValue = UUID.fromString("11111111-1111-1111-1111-111111111111");
|
|
||||||
testCase.resourceSetter.accept(patchResource, JsonNullable.of(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("testCaseArguments")
|
|
||||||
void willPatchOnlyGivenPropertyToNull(final TestCase testCase) {
|
|
||||||
assumeThat(testCase.nullable).isTrue();
|
|
||||||
|
|
||||||
// given
|
|
||||||
final var givenEntity = newInitialEntity();
|
|
||||||
final var patchResource = newPatchResource();
|
|
||||||
testCase.resourceSetter.accept(patchResource, JsonNullable.of(null));
|
|
||||||
|
|
||||||
// when
|
|
||||||
createPatcher(givenEntity).apply(patchResource);
|
|
||||||
|
|
||||||
// then
|
|
||||||
final var expectedEntity = newInitialEntity();
|
|
||||||
testCase.entitySetter.accept(expectedEntity, null);
|
|
||||||
assertThat(givenEntity).usingRecursiveComparison().isEqualTo(expectedEntity);
|
|
||||||
}
|
|
||||||
|
|
||||||
@ParameterizedTest
|
|
||||||
@MethodSource("testCaseArguments")
|
|
||||||
void willThrowExceptionIfResourcePropertyIsNull(final TestCase testCase) {
|
|
||||||
assumeThat(testCase.nullable).isFalse();
|
|
||||||
|
|
||||||
// given
|
|
||||||
final var givenEntity = newInitialEntity();
|
|
||||||
final var patchResource = newPatchResource();
|
|
||||||
testCase.resourceSetter.accept(patchResource, JsonNullable.of(null));
|
|
||||||
|
|
||||||
// when
|
|
||||||
final var actualException = catchThrowableOfType(
|
|
||||||
() -> createPatcher(givenEntity).apply(patchResource),
|
|
||||||
IllegalArgumentException.class);
|
|
||||||
|
|
||||||
// then
|
|
||||||
assertThat(actualException).hasMessage("property '" + testCase.name + "' must not be null");
|
|
||||||
assertThat(givenEntity).usingRecursiveComparison().isEqualTo(newInitialEntity());
|
|
||||||
}
|
|
||||||
|
|
||||||
@ParameterizedTest
|
|
||||||
@MethodSource("testCaseArguments")
|
|
||||||
void willNotPatchIfGivenPropertyNotGiven(final TestCase testCase) {
|
|
||||||
|
|
||||||
// given
|
|
||||||
final var givenEntity = newInitialEntity();
|
|
||||||
final var patchResource = newPatchResource();
|
|
||||||
testCase.resourceSetter.accept(patchResource, null);
|
|
||||||
|
|
||||||
// when
|
|
||||||
createPatcher(givenEntity).apply(patchResource);
|
|
||||||
|
|
||||||
// then
|
|
||||||
final var expectedEntity = newInitialEntity();
|
|
||||||
assertThat(givenEntity).usingRecursiveComparison().isEqualTo(expectedEntity);
|
|
||||||
}
|
|
||||||
|
|
||||||
abstract E newInitialEntity();
|
|
||||||
|
|
||||||
abstract R newPatchResource();
|
|
||||||
|
|
||||||
abstract EntityPatch<R> createPatcher(final E entity);
|
|
||||||
|
|
||||||
abstract Stream<TestCase> testCases();
|
|
||||||
|
|
||||||
Stream<Arguments> testCaseArguments() {
|
|
||||||
return testCases().map(tc -> Arguments.of(Named.of(tc.name, tc)));
|
|
||||||
}
|
|
||||||
|
|
||||||
class TestCase {
|
|
||||||
|
|
||||||
private final String name;
|
|
||||||
public final Object givenPatchedValue;
|
|
||||||
private final BiConsumer<Object, JsonNullable<?>> resourceSetter;
|
|
||||||
private final BiConsumer<Object, Object> entitySetter;
|
|
||||||
private final Object expectedPatchValue;
|
|
||||||
|
|
||||||
private boolean nullable = true;
|
|
||||||
private boolean resolvesUuid = false;
|
|
||||||
|
|
||||||
<R, V, E> TestCase(
|
|
||||||
final String name,
|
|
||||||
final BiConsumer<R, JsonNullable<V>> resourceSetter,
|
|
||||||
final V givenPatchValue,
|
|
||||||
final BiConsumer<E, V> entitySetter
|
|
||||||
) {
|
|
||||||
this.name = name;
|
|
||||||
this.resourceSetter = (BiConsumer<Object, JsonNullable<?>>) (BiConsumer) resourceSetter;
|
|
||||||
this.givenPatchedValue = givenPatchValue;
|
|
||||||
this.entitySetter = (BiConsumer<Object, Object>) entitySetter;
|
|
||||||
this.expectedPatchValue = givenPatchValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
<R, V, E, S> TestCase(
|
|
||||||
final String name,
|
|
||||||
final BiConsumer<R, JsonNullable<V>> resourceSetter,
|
|
||||||
final V givenPatchValue,
|
|
||||||
final BiConsumer<E, S> entitySetter,
|
|
||||||
final S expectedPatchValue
|
|
||||||
) {
|
|
||||||
this.name = name;
|
|
||||||
this.resourceSetter = (BiConsumer<Object, JsonNullable<?>>) (BiConsumer) resourceSetter;
|
|
||||||
this.givenPatchedValue = givenPatchValue;
|
|
||||||
this.entitySetter = (BiConsumer<Object, Object>) entitySetter;
|
|
||||||
this.expectedPatchValue = expectedPatchValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
TestCase notNullable() {
|
|
||||||
nullable = false;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
TestCase resolvesUuid() {
|
|
||||||
resolvesUuid = true;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,153 +1,70 @@
|
|||||||
package net.hostsharing.hsadminng.hs.office.person;
|
package net.hostsharing.hsadminng.hs.office.person;
|
||||||
|
|
||||||
|
import net.hostsharing.hsadminng.PatchUnitTestBase;
|
||||||
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficePersonPatchResource;
|
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficePersonPatchResource;
|
||||||
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficePersonTypeResource;
|
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficePersonTypeResource;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.TestInstance;
|
||||||
import org.junit.jupiter.params.ParameterizedTest;
|
|
||||||
import org.junit.jupiter.params.provider.EnumSource;
|
|
||||||
import org.junit.jupiter.params.provider.NullSource;
|
|
||||||
import org.junit.jupiter.params.provider.ValueSource;
|
|
||||||
import org.openapitools.jackson.nullable.JsonNullable;
|
|
||||||
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.junit.jupiter.api.TestInstance.Lifecycle.PER_CLASS;
|
||||||
|
|
||||||
// TODO: there must be an easier way to test such patch classes
|
@TestInstance(PER_CLASS)
|
||||||
class HsOfficePersonEntityPatchUnitTest {
|
class HsOfficePersonEntityPatchUnitTest extends PatchUnitTestBase<
|
||||||
|
HsOfficePersonPatchResource,
|
||||||
|
HsOfficePersonEntity
|
||||||
|
> {
|
||||||
|
|
||||||
private static final UUID INITIAL_PERSON_UUID = UUID.randomUUID();
|
private static final UUID INITIAL_PERSON_UUID = UUID.randomUUID();
|
||||||
final HsOfficePersonEntity givenPerson = new HsOfficePersonEntity();
|
|
||||||
final HsOfficePersonPatchResource patchResource = new HsOfficePersonPatchResource();
|
|
||||||
|
|
||||||
private final HsOfficePersonEntityPatch hsOfficePersonEntityPatch =
|
@Override
|
||||||
new HsOfficePersonEntityPatch(givenPerson);
|
protected HsOfficePersonEntity newInitialEntity() {
|
||||||
|
final var entity = new HsOfficePersonEntity();
|
||||||
{
|
entity.setUuid(INITIAL_PERSON_UUID);
|
||||||
givenPerson.setUuid(INITIAL_PERSON_UUID);
|
entity.setPersonType(HsOfficePersonType.LEGAL);
|
||||||
givenPerson.setPersonType(HsOfficePersonType.LEGAL);
|
entity.setTradeName("initial@example.org");
|
||||||
givenPerson.setTradeName("initial@example.org");
|
entity.setFamilyName("initial postal address");
|
||||||
givenPerson.setFamilyName("initial postal address");
|
entity.setGivenName("+01 100 123456789");
|
||||||
givenPerson.setGivenName("+01 100 123456789");
|
return entity;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Override
|
||||||
void willPatchAllProperties() {
|
protected HsOfficePersonPatchResource newPatchResource() {
|
||||||
// given
|
return new HsOfficePersonPatchResource();
|
||||||
patchResource.setPersonType(HsOfficePersonTypeResource.NATURAL);
|
|
||||||
patchResource.setTradeName(JsonNullable.of("patched@example.org"));
|
|
||||||
patchResource.setFamilyName(JsonNullable.of("patched postal address"));
|
|
||||||
patchResource.setGivenName(JsonNullable.of("+01 200 987654321"));
|
|
||||||
|
|
||||||
// when
|
|
||||||
hsOfficePersonEntityPatch.apply(patchResource);
|
|
||||||
|
|
||||||
// then
|
|
||||||
new HsOfficePersonEntityMatcher()
|
|
||||||
.withPatchedPersonType(HsOfficePersonType.NATURAL)
|
|
||||||
.withPatchedTradeName("patched@example.org")
|
|
||||||
.withPatchedFamilyName("patched postal address")
|
|
||||||
.withPatchedGivenName("+01 200 987654321")
|
|
||||||
.matches(givenPerson);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ParameterizedTest
|
@Override
|
||||||
@EnumSource(HsOfficePersonTypeResource.class)
|
protected HsOfficePersonEntityPatch createPatcher(final HsOfficePersonEntity entity) {
|
||||||
void willPatchOnlyPersonTypeProperty(final HsOfficePersonTypeResource patchedValue) {
|
return new HsOfficePersonEntityPatch(entity);
|
||||||
// given
|
|
||||||
patchResource.setPersonType(patchedValue);
|
|
||||||
|
|
||||||
// when
|
|
||||||
hsOfficePersonEntityPatch.apply(patchResource);
|
|
||||||
|
|
||||||
// then
|
|
||||||
new HsOfficePersonEntityMatcher()
|
|
||||||
.withPatchedPersonType(HsOfficePersonType.valueOf(patchedValue.getValue()))
|
|
||||||
.matches(givenPerson);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ParameterizedTest
|
@Override
|
||||||
@ValueSource(strings = { "patched@example.org" })
|
protected Stream<Property> propertyTestDescriptors() {
|
||||||
@NullSource
|
return Stream.of(
|
||||||
void willPatchOnlyTradeNameProperty(final String patchedValue) {
|
new SimpleProperty<>(
|
||||||
// given
|
"personType",
|
||||||
patchResource.setTradeName(JsonNullable.of(patchedValue));
|
HsOfficePersonPatchResource::setPersonType,
|
||||||
|
HsOfficePersonTypeResource.SOLE_REPRESENTATION,
|
||||||
// when
|
HsOfficePersonEntity::setPersonType,
|
||||||
hsOfficePersonEntityPatch.apply(patchResource);
|
HsOfficePersonType.SOLE_REPRESENTATION)
|
||||||
|
.notNullable(),
|
||||||
// then
|
new JsonNullableProperty<>(
|
||||||
new HsOfficePersonEntityMatcher()
|
"tradeName",
|
||||||
.withPatchedTradeName(patchedValue)
|
HsOfficePersonPatchResource::setTradeName,
|
||||||
.matches(givenPerson);
|
"patched trade name",
|
||||||
|
HsOfficePersonEntity::setTradeName),
|
||||||
|
new JsonNullableProperty<>(
|
||||||
|
"familyName",
|
||||||
|
HsOfficePersonPatchResource::setFamilyName,
|
||||||
|
"patched family name",
|
||||||
|
HsOfficePersonEntity::setFamilyName),
|
||||||
|
new JsonNullableProperty<>(
|
||||||
|
"patched given name",
|
||||||
|
HsOfficePersonPatchResource::setGivenName,
|
||||||
|
"patched given name",
|
||||||
|
HsOfficePersonEntity::setGivenName)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ParameterizedTest
|
|
||||||
@ValueSource(strings = { "patched postal address" })
|
|
||||||
@NullSource
|
|
||||||
void willPatchOnlyFamilyNameProperty(final String patchedValue) {
|
|
||||||
// given
|
|
||||||
patchResource.setFamilyName(JsonNullable.of(patchedValue));
|
|
||||||
|
|
||||||
// when
|
|
||||||
hsOfficePersonEntityPatch.apply(patchResource);
|
|
||||||
|
|
||||||
// then
|
|
||||||
new HsOfficePersonEntityMatcher()
|
|
||||||
.withPatchedFamilyName(patchedValue)
|
|
||||||
.matches(givenPerson);
|
|
||||||
}
|
|
||||||
|
|
||||||
@ParameterizedTest
|
|
||||||
@ValueSource(strings = { "+01 200 987654321" })
|
|
||||||
@NullSource
|
|
||||||
void willPatchOnlyGivenNameProperty(final String patchedValue) {
|
|
||||||
// given
|
|
||||||
patchResource.setGivenName(JsonNullable.of(patchedValue));
|
|
||||||
|
|
||||||
// when
|
|
||||||
hsOfficePersonEntityPatch.apply(patchResource);
|
|
||||||
|
|
||||||
// then
|
|
||||||
new HsOfficePersonEntityMatcher()
|
|
||||||
.withPatchedGivenName(patchedValue)
|
|
||||||
.matches(givenPerson);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static class HsOfficePersonEntityMatcher {
|
|
||||||
|
|
||||||
private HsOfficePersonType expectedPersonType = HsOfficePersonType.LEGAL;
|
|
||||||
private String expectedTradeName = "initial@example.org";
|
|
||||||
private String expectedFamilyName = "initial postal address";
|
|
||||||
|
|
||||||
private String expectedGivenName = "+01 100 123456789";
|
|
||||||
|
|
||||||
HsOfficePersonEntityMatcher withPatchedPersonType(final HsOfficePersonType patchedPersonType) {
|
|
||||||
expectedPersonType = patchedPersonType;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
HsOfficePersonEntityMatcher withPatchedTradeName(final String patchedTradeName) {
|
|
||||||
expectedTradeName = patchedTradeName;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
HsOfficePersonEntityMatcher withPatchedFamilyName(final String patchedFamilyName) {
|
|
||||||
expectedFamilyName = patchedFamilyName;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
HsOfficePersonEntityMatcher withPatchedGivenName(final String patchedGivenName) {
|
|
||||||
expectedGivenName = patchedGivenName;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
void matches(final HsOfficePersonEntity givenPerson) {
|
|
||||||
|
|
||||||
assertThat(givenPerson.getPersonType()).isEqualTo(expectedPersonType);
|
|
||||||
assertThat(givenPerson.getTradeName()).isEqualTo(expectedTradeName);
|
|
||||||
assertThat(givenPerson.getFamilyName()).isEqualTo(expectedFamilyName);
|
|
||||||
assertThat(givenPerson.getGivenName()).isEqualTo(expectedGivenName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user