diff --git a/alfa-service/src/main/java/de/ozgcloud/alfa/common/LinkedUserProfileResourceSerializer.java b/alfa-service/src/main/java/de/ozgcloud/alfa/common/LinkedUserProfileResourceSerializer.java index 59520565f0a309e9b1a67367fa777fd2f7b36bf4..582ad419b2abd5a160e3b5ceb124d84114c49d87 100644 --- a/alfa-service/src/main/java/de/ozgcloud/alfa/common/LinkedUserProfileResourceSerializer.java +++ b/alfa-service/src/main/java/de/ozgcloud/alfa/common/LinkedUserProfileResourceSerializer.java @@ -49,7 +49,7 @@ public class LinkedUserProfileResourceSerializer extends JsonSerializer<Object> private LinkedUserProfileResource annotation; - private static LinkedUserProfileResourceSerializer createContectualSerializer(UserManagerUrlProvider userManagerUrlProvider, LinkedUserProfileResource annotation) { + static LinkedUserProfileResourceSerializer createForAnnotatedField(UserManagerUrlProvider userManagerUrlProvider, LinkedUserProfileResource annotation) { var serializer = new LinkedUserProfileResourceSerializer(userManagerUrlProvider); serializer.annotation = annotation; return serializer; @@ -57,10 +57,21 @@ public class LinkedUserProfileResourceSerializer extends JsonSerializer<Object> @Override public JsonSerializer<?> createContextual(SerializerProvider prov, BeanProperty property) { - return LinkedUserProfileResourceSerializer.createContectualSerializer(userManagerUrlProvider, property.getAnnotation(LinkedUserProfileResource.class)); + return LinkedUserProfileResourceSerializer.createForAnnotatedField(userManagerUrlProvider, property.getAnnotation(LinkedUserProfileResource.class)); } - String buildLink(Object id) { + @Override + public void serialize(Object value, JsonGenerator gen, SerializerProvider serializers) throws IOException { + if (value instanceof Collection) { + gen.writeStartArray(); + ((Collection<?>) value).forEach(val -> writeObject(gen, buildLink(val))); + gen.writeEndArray(); + } else { + writeObject(gen, buildLink(value)); + } + } + + private String buildLink(Object id) { return userManagerUrlProvider.isConfiguredForUserProfile() ? Link.of(buildUserProfileUri(id.toString())).getHref() : String.valueOf(id); @@ -70,7 +81,7 @@ public class LinkedUserProfileResourceSerializer extends JsonSerializer<Object> return String.format(userManagerUrlProvider.getUserProfileTemplate(), getExtractor().extractId(id)); } - IdExtractor<Object> getExtractor() { + private IdExtractor<Object> getExtractor() { try { return ConstructorUtils.invokeConstructor(annotation.extractor()); } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException | InstantiationException e) { @@ -78,18 +89,7 @@ public class LinkedUserProfileResourceSerializer extends JsonSerializer<Object> } } - @Override - public void serialize(Object value, JsonGenerator gen, SerializerProvider serializers) throws IOException { - if (value instanceof Collection) { - gen.writeStartArray(); - ((Collection<?>) value).forEach(val -> writeObject(gen, buildLink(val))); - gen.writeEndArray(); - } else { - writeObject(gen, buildLink(value)); - } - } - - void writeObject(JsonGenerator gen, Object value) { + private void writeObject(JsonGenerator gen, Object value) { try { gen.writeObject(value); } catch (IOException e) { diff --git a/alfa-service/src/test/java/de/ozgcloud/alfa/common/LinkedUserProfileResourceSerializerITCase.java b/alfa-service/src/test/java/de/ozgcloud/alfa/common/LinkedUserProfileResourceSerializerITCase.java index 2879f2297de17fb3a0bbf327c2285b29f52805ee..ca3058226b1c21a358db5a68e879a7869fb6b339 100644 --- a/alfa-service/src/test/java/de/ozgcloud/alfa/common/LinkedUserProfileResourceSerializerITCase.java +++ b/alfa-service/src/test/java/de/ozgcloud/alfa/common/LinkedUserProfileResourceSerializerITCase.java @@ -27,7 +27,6 @@ import static org.assertj.core.api.Assertions.*; import static org.mockito.Mockito.*; import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.context.bean.override.mockito.MockitoBean; @@ -42,47 +41,28 @@ import de.ozgcloud.common.test.ITCase; @ITCase class LinkedUserProfileResourceSerializerITCase { + private static final String HTTP_LOCALHOST = "http://localhost/"; + private static final String API_TEMPLATE = "api/profile/%s"; + private static final String API_PATH = "api/profile/"; + @MockitoBean private UserManagerUrlProvider userManagerUrlProvider; @Autowired private ObjectMapper objectMapper; - @Nested - class TestSerialization { - - private final LinkedUserProfileResourceTestObject testObj = new LinkedUserProfileResourceTestObject(UserProfileTestFactory.ID); - - @Nested - class OnIsUrlConfigured { - - private static final String HTTP_LOCALHOST = "http://localhost/"; - private static final String API_TEMPLATE = "api/profile/%s"; - private static final String API_PATH = "api/profile/"; - - @BeforeEach - void init() { - when(userManagerUrlProvider.isConfiguredForUserProfile()).thenReturn(true); - when(userManagerUrlProvider.getUserProfileTemplate()).thenReturn(HTTP_LOCALHOST + API_TEMPLATE); - } - - @Test - void shouldSerializeToUrl() throws JsonProcessingException { - var serialized = objectMapper.writeValueAsString(testObj); - - assertThat(serialized).isEqualTo("{\"id\":\"" + HTTP_LOCALHOST + API_PATH + UserProfileTestFactory.ID.toString() + "\"}"); - } - } + @BeforeEach + void init() { + when(userManagerUrlProvider.isConfiguredForUserProfile()).thenReturn(true); + when(userManagerUrlProvider.getUserProfileTemplate()).thenReturn(HTTP_LOCALHOST + API_TEMPLATE); + } - @Nested - class OnUrlIsNotConfigured { + @Test + void shouldSerialize() throws JsonProcessingException { + var testObj = new LinkedUserProfileResourceTestObject(UserProfileTestFactory.ID); - @Test - void shouldSerializeToId() throws JsonProcessingException { - var serialized = objectMapper.writeValueAsString(testObj); + var serialized = objectMapper.writeValueAsString(testObj); - assertThat(serialized).isEqualTo("{\"id\":\"" + UserProfileTestFactory.ID.toString() + "\"}"); - } - } + assertThat(serialized).isEqualTo("{\"id\":\"" + HTTP_LOCALHOST + API_PATH + UserProfileTestFactory.ID.toString() + "\"}"); } } diff --git a/alfa-service/src/test/java/de/ozgcloud/alfa/common/LinkedUserProfileResourceSerializerTest.java b/alfa-service/src/test/java/de/ozgcloud/alfa/common/LinkedUserProfileResourceSerializerTest.java index 05aefe6e1c4ed6ff64875d4efbd5416ecb46e187..31f1031218762d56ea641f5feb4e116555fe3420 100644 --- a/alfa-service/src/test/java/de/ozgcloud/alfa/common/LinkedUserProfileResourceSerializerTest.java +++ b/alfa-service/src/test/java/de/ozgcloud/alfa/common/LinkedUserProfileResourceSerializerTest.java @@ -3,73 +3,107 @@ package de.ozgcloud.alfa.common; import static org.assertj.core.api.Assertions.*; import static org.mockito.Mockito.*; +import java.util.List; import java.util.UUID; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; -import org.mockito.InjectMocks; +import org.mockito.ArgumentCaptor; +import org.mockito.Captor; import org.mockito.Mock; -import org.mockito.Spy; +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.SerializerProvider; + +import de.ozgcloud.alfa.common.user.UserId; import de.ozgcloud.alfa.common.user.UserManagerUrlProvider; -import de.ozgcloud.alfa.common.user.UserProfileTestFactory; +import lombok.SneakyThrows; class LinkedUserProfileResourceSerializerTest { - @Spy - @InjectMocks - private LinkedUserProfileResourceSerializer serializer; + private static final LinkedUserProfileResource ANNOTATION = getAnnotation(); + @Mock private UserManagerUrlProvider userManagerUrlProvider; - private static final String USER_PROFILE_URL_TEMPLATE = "DummyUserProfileUrlTemplate/%s"; + private LinkedUserProfileResourceSerializer serializer; + + @BeforeEach + void init() { + serializer = LinkedUserProfileResourceSerializer.createForAnnotatedField(userManagerUrlProvider, ANNOTATION); + } @Nested - class TestBuildLink { + class TestSerialize { - @Test - void shouldCheckIfUrlIsConfigured() { - buildLink(); + private static final UserId USER_ID = UserId.from(UUID.randomUUID()); + private static final UserId USER_ID_2 = UserId.from(UUID.randomUUID()); - verify(userManagerUrlProvider).isConfiguredForUserProfile(); - } + @Mock + private JsonGenerator generator; + @Mock + private SerializerProvider serializerProvider; + @Captor + private ArgumentCaptor<Object> writtenObjectCaptor; @Nested class OnUrlIsConfigured { - private static final String EXTRACTED_ID = UUID.randomUUID().toString(); - - @Mock - private IdExtractor<Object> extractor; + private static final String HTTP_LOCALHOST = "http://localhost/"; + private static final String API_TEMPLATE = "api/profile/%s"; + private static final String API_PATH = "api/profile/"; @BeforeEach void init() { when(userManagerUrlProvider.isConfiguredForUserProfile()).thenReturn(true); - when(userManagerUrlProvider.getUserProfileTemplate()).thenReturn(USER_PROFILE_URL_TEMPLATE); - doReturn(extractor).when(serializer).getExtractor(); - when(extractor.extractId(any())).thenReturn(EXTRACTED_ID); + when(userManagerUrlProvider.getUserProfileTemplate()).thenReturn(HTTP_LOCALHOST + API_TEMPLATE); } - @Test - void shouldCallProvider() { - buildLink(); + @Nested + class OnSingularValue { + + @SneakyThrows + @Test + void shouldSerializeToUrl() { + serializeSingleValue(); - verify(userManagerUrlProvider).getUserProfileTemplate(); + verify(generator).writeObject(writtenObjectCaptor.capture()); + assertThat(writtenObjectCaptor.getValue()).isEqualTo(expectedUrl(USER_ID)); + } } - @Test - void shouldExtractId() { - buildLink(); + @Nested + class OnCollection { - verify(extractor).extractId(UserProfileTestFactory.ID.toString()); - } + @SneakyThrows + @Test + void shouldWriteStartArray() { + serializeCollection(); + + verify(generator).writeStartArray(); + } + + @SneakyThrows + @Test + void shouldSerializeToUrls() { + serializeCollection(); + + verify(generator, times(2)).writeObject(writtenObjectCaptor.capture()); + assertThat(writtenObjectCaptor.getAllValues()).containsExactly(expectedUrl(USER_ID), expectedUrl(USER_ID_2)); + } + + @SneakyThrows + @Test + void shouldWriteEndArray() { + serializeCollection(); - @Test - void shouldReturnLink() { - var link = buildLink(); + verify(generator).writeEndArray(); + } + } - assertThat(link).isEqualTo("DummyUserProfileUrlTemplate/" + EXTRACTED_ID); + private String expectedUrl(UserId id) { + return HTTP_LOCALHOST + API_PATH + id.toString(); } } @@ -81,16 +115,63 @@ class LinkedUserProfileResourceSerializerTest { when(userManagerUrlProvider.isConfiguredForUserProfile()).thenReturn(false); } - @Test - void shouldReturnStringValueOfId() { - var link = buildLink(); + @Nested + class OnSingularValue { + + @SneakyThrows + @Test + void shouldSerializeToString() { + serializeSingleValue(); + + verify(generator).writeObject(writtenObjectCaptor.capture()); + assertThat(writtenObjectCaptor.getValue()).isEqualTo(USER_ID.toString()); + } + } + + @Nested + class OnCollection { + + @SneakyThrows + @Test + void shouldWriteStartArray() { + serializeCollection(); + + verify(generator).writeStartArray(); + } - assertThat(link).isEqualTo(UserProfileTestFactory.ID.toString()); + @SneakyThrows + @Test + void shouldSerializeToUrls() { + serializeCollection(); + + verify(generator, times(2)).writeObject(writtenObjectCaptor.capture()); + assertThat(writtenObjectCaptor.getAllValues()).containsExactly(USER_ID.toString(), USER_ID_2.toString()); + } + + @SneakyThrows + @Test + void shouldWriteEndArray() { + serializeCollection(); + + verify(generator).writeEndArray(); + } } } - private String buildLink() { - return serializer.buildLink(UserProfileTestFactory.ID); + @SneakyThrows + private void serializeSingleValue() { + serializer.serialize(USER_ID, generator, serializerProvider); } + + @SneakyThrows + private void serializeCollection() { + serializer.serialize(List.of(USER_ID, USER_ID_2), generator, serializerProvider); + } + } + + @SneakyThrows + private static LinkedUserProfileResource getAnnotation() { + var idField = LinkedUserProfileResourceTestObject.class.getDeclaredField("id"); + return idField.getDeclaredAnnotation(LinkedUserProfileResource.class); } }