extract OptionalFromJson for JSON mapper bug

This commit is contained in:
Michael Hoennig 2022-08-09 18:30:06 +02:00
parent 0e4602aac6
commit 5ebed0f75d
3 changed files with 90 additions and 6 deletions

View File

@ -0,0 +1,29 @@
package net.hostsharing.hsadminng;
import org.openapitools.jackson.nullable.JsonNullable;
import java.util.function.Consumer;
public class OptionalFromJson<T> {
private final JsonNullable<T> optionalNullableValueFromJson;
public OptionalFromJson(final JsonNullable<T> optionalNullableValueFromJson) {
this.optionalNullableValueFromJson = optionalNullableValueFromJson;
}
public static <T> OptionalFromJson<T> of(final JsonNullable<T> optionalNullableValueFromJson) {
return new OptionalFromJson<>(optionalNullableValueFromJson);
}
public void ifPresent(final Consumer<T> setter) {
// It looks like a bug to me, that the JsonNullable itself is null if the element was not in the JSON;
// and if it is not null, isPresent() always returns true and thus ifPresent() always fires.
// Instead there should always be a JsonNullable instance
// and ifPresent() should only fire if the element was actually in th JSON.
if (optionalNullableValueFromJson != null) {
// this will work with the bug as well as without
optionalNullableValueFromJson.ifPresent(setter);
}
}
}

View File

@ -1,5 +1,6 @@
package net.hostsharing.hsadminng.hs.hspackage; package net.hostsharing.hsadminng.hs.hspackage;
import net.hostsharing.hsadminng.OptionalFromJson;
import net.hostsharing.hsadminng.context.Context; import net.hostsharing.hsadminng.context.Context;
import net.hostsharing.hsadminng.generated.api.v1.api.PackagesApi; import net.hostsharing.hsadminng.generated.api.v1.api.PackagesApi;
import net.hostsharing.hsadminng.generated.api.v1.model.PackageResource; import net.hostsharing.hsadminng.generated.api.v1.model.PackageResource;
@ -52,14 +53,9 @@ public class PackageController implements PackagesApi {
context.assumeRoles(assumedRoles); context.assumeRoles(assumedRoles);
} }
final var current = packageRepository.findByUuid(packageUuid); final var current = packageRepository.findByUuid(packageUuid);
if (body.getDescription() != null) { OptionalFromJson.of(body.getDescription()).ifPresent(current::setDescription);
body.getDescription().ifPresent(current::setDescription);
} else {
body.toString();
}
final var saved = packageRepository.save(current); final var saved = packageRepository.save(current);
final var mapped = map(saved, PackageResource.class); final var mapped = map(saved, PackageResource.class);
return ResponseEntity.ok(mapped); return ResponseEntity.ok(mapped);
} }
} }

View File

@ -0,0 +1,59 @@
package net.hostsharing.hsadminng;
import org.junit.jupiter.api.Test;
import org.openapitools.jackson.nullable.JsonNullable;
import static org.assertj.core.api.Assertions.assertThat;
class OptionalFromJsonUnitTest {
private String value = "unchanged initial value";
@Test
void shouldHandleActualValue() {
// given
final JsonNullable<String> given = JsonNullable.of("actual new value");
// when
OptionalFromJson.of(given).ifPresent(valueFromJson -> value = valueFromJson);
// then
assertThat(value).isEqualTo("actual new value");
}
@Test
void shouldHandleNullValue() {
// given
final JsonNullable<String> given = JsonNullable.of(null);
// when
OptionalFromJson.of(given).ifPresent(valueFromJson -> value = valueFromJson);
// then
assertThat(value).isNull();
}
@Test
void shouldHandleUndefinedValue() {
// given - what should have happen in the JSON mapper
final JsonNullable<String> given = JsonNullable.undefined();
// when
OptionalFromJson.of(given).ifPresent(valueFromJson -> value = valueFromJson);
// then
assertThat(value).isEqualTo("unchanged initial value");
}
@Test
void shouldHandleInvalidNullJsonNullable() {
// given - what seems to happen in the JSON mapper
final JsonNullable<String> given = null;
// when
OptionalFromJson.of(given).ifPresent(valueFromJson -> value = valueFromJson);
// then
assertThat(value).isEqualTo("unchanged initial value");
}
}