diff --git a/alfa-xdomea/pom.xml b/alfa-xdomea/pom.xml index 8f5d2c08a3647c90e5905617eed3eee3778e4a3a..d4d2b5b35dfad832f17fc795dc7cc62b9ef7b249 100644 --- a/alfa-xdomea/pom.xml +++ b/alfa-xdomea/pom.xml @@ -93,7 +93,7 @@ </executions> <configuration> <sources> - <source>src/main/resources/xdomea_3-0-0_XML-Schemata</source> + <source>src/main/resources/ozgcloud_XML-Schemata</source> </sources> <packageName>de.xoev.xdomea</packageName> </configuration> diff --git a/alfa-xdomea/src/main/java/de/ozgcloud/alfa/vorgang/AnwendungsspezifischeErweiterungTypeCreator.java b/alfa-xdomea/src/main/java/de/ozgcloud/alfa/vorgang/AnwendungsspezifischeErweiterungTypeCreator.java index 2c3deedcc986cf1f382082da479dc4fc826bd369..0e98a75fee4b6339c8a5db5d74aaddfc043a7017 100644 --- a/alfa-xdomea/src/main/java/de/ozgcloud/alfa/vorgang/AnwendungsspezifischeErweiterungTypeCreator.java +++ b/alfa-xdomea/src/main/java/de/ozgcloud/alfa/vorgang/AnwendungsspezifischeErweiterungTypeCreator.java @@ -6,6 +6,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import de.xoev.xdomea.AnwendungsspezifischeErweiterungType; +import de.xoev.xdomea.OzgcloudErweiterungType; @Component class AnwendungsspezifischeErweiterungTypeCreator { @@ -15,12 +16,16 @@ class AnwendungsspezifischeErweiterungTypeCreator { @Autowired private FeldGruppeTypeCreator feldGruppeTypeCreator; + @Autowired + private FormDataMapper formDataMapper; public AnwendungsspezifischeErweiterungType create(VorgangWithEingang vorgang) { - var anwendungsspezifischeErweiterung = new AnwendungsspezifischeErweiterungType(); - anwendungsspezifischeErweiterung.setKennung(KENNUNG); - anwendungsspezifischeErweiterung.setName(NAME); - anwendungsspezifischeErweiterung.getFeldgruppe().addAll(Collections.singleton(feldGruppeTypeCreator.create(vorgang))); - return anwendungsspezifischeErweiterung; + var ozgcloudErweiterungType = new OzgcloudErweiterungType(); + ozgcloudErweiterungType.setKennung(KENNUNG); + ozgcloudErweiterungType.setName(NAME); + ozgcloudErweiterungType.getFeldgruppe().addAll(Collections.singleton(feldGruppeTypeCreator.create(vorgang))); + ozgcloudErweiterungType.setAntragsdaten(formDataMapper.toAntragsdatenType(vorgang)); + return ozgcloudErweiterungType; } + } diff --git a/alfa-xdomea/src/main/java/de/ozgcloud/alfa/vorgang/DatatypeMapper.java b/alfa-xdomea/src/main/java/de/ozgcloud/alfa/vorgang/DatatypeMapper.java new file mode 100644 index 0000000000000000000000000000000000000000..9a740682a45f0793f2926172b98212060617c603 --- /dev/null +++ b/alfa-xdomea/src/main/java/de/ozgcloud/alfa/vorgang/DatatypeMapper.java @@ -0,0 +1,44 @@ +package de.ozgcloud.alfa.vorgang; + +import static java.util.Objects.*; + +import java.time.LocalDate; +import java.time.ZonedDateTime; +import java.util.Collection; + +import org.springframework.stereotype.Component; + +import de.xoev.xdomea.DatatypeType; + +@Component +class DatatypeMapper { + + public DatatypeType from(Object object) { + if (isNull(object)) { + return DatatypeType.STRING; + } + var objectClass = object.getClass(); + if (String.class.equals(objectClass)) { + return DatatypeType.STRING; + } + if (Integer.class.equals(objectClass)) { + return DatatypeType.INTEGER; + } + if (Boolean.class.equals(objectClass)) { + return DatatypeType.BOOLEAN; + } + if (LocalDate.class.equals(objectClass)) { + return DatatypeType.DATE; + } + if (ZonedDateTime.class.equals(objectClass)) { + return DatatypeType.DATETIME; + } + if (Float.class.equals(objectClass)) { + return DatatypeType.FLOAT; + } + if (object instanceof Collection<?> collection && !collection.isEmpty()) { + return from(collection.iterator().next()); + } + return DatatypeType.STRING; + } +} diff --git a/alfa-xdomea/src/main/java/de/ozgcloud/alfa/vorgang/FormDataMapper.java b/alfa-xdomea/src/main/java/de/ozgcloud/alfa/vorgang/FormDataMapper.java new file mode 100644 index 0000000000000000000000000000000000000000..e2aba0f9fde6b7f2ae5d0c515ba95d70e3cf6d78 --- /dev/null +++ b/alfa-xdomea/src/main/java/de/ozgcloud/alfa/vorgang/FormDataMapper.java @@ -0,0 +1,93 @@ +package de.ozgcloud.alfa.vorgang; + +import java.time.ZonedDateTime; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.Optional; + +import jakarta.validation.constraints.NotNull; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import de.ozgcloud.alfa.common.DateConverter; +import de.xoev.xdomea.AntragsdatenGroupType; +import de.xoev.xdomea.AntragsdatenItemType; +import de.xoev.xdomea.AntragsdatenMultiValueFieldType; +import de.xoev.xdomea.AntragsdatenSingleValueFieldType; +import de.xoev.xdomea.AntragsdatenType; +import de.xoev.xdomea.DatatypeType; +import de.xoev.xdomea.ItemListType; + +@Component +class FormDataMapper { + + @Autowired + private DatatypeMapper datatypeMapper; + @Autowired + private DateConverter dateConverter; + + public AntragsdatenType toAntragsdatenType(@NotNull VorgangWithEingang vorgang) { + return Optional.ofNullable(vorgang.getEingang()).map(Eingang::getFormData).map(this::buileItemListType).map(AntragsdatenType.class::cast) + .orElseGet(AntragsdatenType::new); + } + + ItemListType buileItemListType(Map<?, ?> formData) { + var itemList = new AntragsdatenType(); + itemList.getItem().addAll(buildItems(formData)); + return itemList; + } + + List<AntragsdatenItemType> buildItems(Map<?, ?> formData) { + var items = new ArrayList<AntragsdatenItemType>(); + for (var formDataEntry : formData.entrySet()) { + var key = (String) formDataEntry.getKey(); + var value = formDataEntry.getValue(); + if (value instanceof Map<?, ?> map) { + items.add(buildAntragsdatenGroup(key, map)); + } else if (value instanceof Collection<?> collection) { + items.add(buildMultiValueField(key, collection)); + } else { + items.add(buildSingleValueField(key, value)); + + } + } + return items; + } + + AntragsdatenItemType buildAntragsdatenGroup(String name, Map<?, ?> values) { + var antragsGroup = new AntragsdatenGroupType(); + antragsGroup.setName(name); + antragsGroup.setValue(buileItemListType(values)); + return antragsGroup; + } + + AntragsdatenItemType buildMultiValueField(String name, Collection<?> values) { + var multiValue = new AntragsdatenMultiValueFieldType(); + multiValue.setName(name); + var datatype = datatypeMapper.from(values); + multiValue.setType(datatype); + var multiValueList = multiValue.getValue(); + values.stream().map(v -> formatValue(datatype, v)).forEach(multiValueList::add); + return multiValue; + } + + AntragsdatenItemType buildSingleValueField(String name, Object value) { + var singleValue = new AntragsdatenSingleValueFieldType(); + singleValue.setName(name); + var datatype = datatypeMapper.from(value); + singleValue.setType(datatype); + singleValue.setValue(formatValue(datatype, value)); + return singleValue; + } + + Object formatValue(DatatypeType datatype, Object value) { + return switch (datatype) { + case STRING -> String.valueOf(value); + case DATETIME -> dateConverter.toXmlGregorianCalendar((ZonedDateTime) value); + default -> value; + }; + } +} diff --git a/alfa-xdomea/src/main/resources/ozgcloud_XML-Schemata/ozgcloud.xsd b/alfa-xdomea/src/main/resources/ozgcloud_XML-Schemata/ozgcloud.xsd new file mode 100644 index 0000000000000000000000000000000000000000..fd20e4462893778c836d38217d2b9d78e1724aa5 --- /dev/null +++ b/alfa-xdomea/src/main/resources/ozgcloud_XML-Schemata/ozgcloud.xsd @@ -0,0 +1,84 @@ +<?xml version="1.0" encoding="UTF-8"?> +<xs:schema targetNamespace="urn:ozgcloud-de:xdomea:schema:1.0.0" + xmlns:ozgcloud="urn:ozgcloud-de:xdomea:schema:1.0.0" + xmlns:xs="http://www.w3.org/2001/XMLSchema" + xmlns:xdomea="urn:xoev-de:xdomea:schema:3.0.0" + elementFormDefault="qualified"> + + <xs:import namespace="urn:xoev-de:xdomea:schema:3.0.0" schemaLocation="../xdomea_3-0-0_XML-Schemata/xdomea.xsd"/> + + <xs:complexType name="OzgcloudErweiterungType"> + <xs:complexContent> + <xs:extension base="xdomea:AnwendungsspezifischeErweiterungType"> + <xs:sequence> + <xs:element name="Antragsdaten" type="ozgcloud:AntragsdatenType"/> + </xs:sequence> + </xs:extension> + </xs:complexContent> + </xs:complexType> + + <xs:complexType name="AntragsdatenType"> + <xs:complexContent> + <xs:extension base="ozgcloud:ItemListType"/> + </xs:complexContent> + </xs:complexType> + + <xs:complexType name="AntragsdatenItemType" abstract="true"> + <xs:attribute name="name" type="xs:string" use="required"/> + </xs:complexType> + + <xs:complexType name="AntragsdatenFieldType" abstract="true"> + <xs:complexContent> + <xs:extension base="ozgcloud:AntragsdatenItemType"> + <xs:attribute name="type" type="ozgcloud:DatatypeType" default="string"/> + </xs:extension> + </xs:complexContent> + </xs:complexType> + + <xs:complexType name="AntragsdatenSingleValueFieldType"> + <xs:complexContent> + <xs:extension base="ozgcloud:AntragsdatenFieldType"> + <xs:all> + <xs:element name="Value" type="xs:anyType"/> + </xs:all> + </xs:extension> + </xs:complexContent> + </xs:complexType> + + <xs:complexType name="AntragsdatenMultiValueFieldType"> + <xs:complexContent> + <xs:extension base="ozgcloud:AntragsdatenFieldType"> + <xs:sequence> + <xs:element name="Value" type="xs:anyType" maxOccurs="unbounded"/> + </xs:sequence> + </xs:extension> + </xs:complexContent> + </xs:complexType> + + <xs:complexType name="AntragsdatenGroupType"> + <xs:complexContent> + <xs:extension base="ozgcloud:AntragsdatenItemType"> + <xs:sequence> + <xs:element name="Value" type="ozgcloud:ItemListType"/> + </xs:sequence> + </xs:extension> + </xs:complexContent> + </xs:complexType> + + <xs:complexType name="ItemListType" abstract="true"> + <xs:sequence> + <xs:element name="Item" type="ozgcloud:AntragsdatenItemType" minOccurs="0" maxOccurs="unbounded"/> + </xs:sequence> + </xs:complexType> + + <xs:simpleType name="DatatypeType"> + <xs:restriction base="xs:string"> + <xs:enumeration value="string"/> + <xs:enumeration value="date"/> + <xs:enumeration value="datetime"/> + <xs:enumeration value="integer"/> + <xs:enumeration value="float"/> + <xs:enumeration value="boolean"/> + </xs:restriction> + </xs:simpleType> +</xs:schema> \ No newline at end of file diff --git a/alfa-xdomea/src/test/java/de/ozgcloud/alfa/vorgang/AntragsdatenItemTypeTestFactory.java b/alfa-xdomea/src/test/java/de/ozgcloud/alfa/vorgang/AntragsdatenItemTypeTestFactory.java new file mode 100644 index 0000000000000000000000000000000000000000..f9d51af847460fcdc73e55073b5caa137021a560 --- /dev/null +++ b/alfa-xdomea/src/test/java/de/ozgcloud/alfa/vorgang/AntragsdatenItemTypeTestFactory.java @@ -0,0 +1,44 @@ +package de.ozgcloud.alfa.vorgang; + +import de.xoev.xdomea.AntragsdatenGroupType; +import de.xoev.xdomea.AntragsdatenMultiValueFieldType; +import de.xoev.xdomea.AntragsdatenSingleValueFieldType; +import de.xoev.xdomea.AntragsdatenType; +import de.xoev.xdomea.DatatypeType; + +public class AntragsdatenItemTypeTestFactory { + + public static final String KEY_STRING = "string"; + public static final String KEY_MAP = "map"; + public static final String KEY_COLLECTION = "collection"; + public static final String VALUE_STRING = "value1"; + public static final Integer VALUE_INTEGER = 1; + + public static AntragsdatenSingleValueFieldType createSingleValueField() { + var antragsdatenItemType = new AntragsdatenSingleValueFieldType(); + antragsdatenItemType.setType(DatatypeType.STRING); + antragsdatenItemType.setName(KEY_STRING); + antragsdatenItemType.setValue(VALUE_STRING); + return antragsdatenItemType; + } + + public static AntragsdatenMultiValueFieldType createMultiValueField() { + var antragsdatenItemType = new AntragsdatenMultiValueFieldType(); + antragsdatenItemType.setType(DatatypeType.INTEGER); + antragsdatenItemType.setName(KEY_COLLECTION); + antragsdatenItemType.getValue().add(VALUE_INTEGER); + return antragsdatenItemType; + } + + public static AntragsdatenGroupType createGroup() { + var antragsdatenItemType = new AntragsdatenGroupType(); + antragsdatenItemType.setName(KEY_MAP); + + var group = new AntragsdatenType(); + group.getItem().add(createMultiValueField()); + antragsdatenItemType.setValue(group); + + return antragsdatenItemType; + } + +} diff --git a/alfa-xdomea/src/test/java/de/ozgcloud/alfa/vorgang/AnwendungsspezifischeErweiterungTypeCreatorTest.java b/alfa-xdomea/src/test/java/de/ozgcloud/alfa/vorgang/AnwendungsspezifischeErweiterungTypeCreatorTest.java index ce274988405747bdcb4c47960c7b96699db5896d..9580936d7e586792190f6a8ca4407b85696b1603 100644 --- a/alfa-xdomea/src/test/java/de/ozgcloud/alfa/vorgang/AnwendungsspezifischeErweiterungTypeCreatorTest.java +++ b/alfa-xdomea/src/test/java/de/ozgcloud/alfa/vorgang/AnwendungsspezifischeErweiterungTypeCreatorTest.java @@ -1,7 +1,9 @@ package de.ozgcloud.alfa.vorgang; -import static org.assertj.core.api.Assertions.*; -import static org.mockito.Mockito.*; +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Nested; @@ -10,8 +12,10 @@ import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.Spy; +import de.xoev.xdomea.AntragsdatenType; import de.xoev.xdomea.AnwendungsspezifischeErweiterungType; import de.xoev.xdomea.FeldgruppeType; +import de.xoev.xdomea.OzgcloudErweiterungType; class AnwendungsspezifischeErweiterungTypeCreatorTest { @@ -21,16 +25,20 @@ class AnwendungsspezifischeErweiterungTypeCreatorTest { @Mock private FeldGruppeTypeCreator feldGruppeTypeCreator; + @Mock + private FormDataMapper formDataMapper; @Nested class TestCreate { private final VorgangWithEingang vorgang = VorgangWithEingangTestFactory.create(); private final FeldgruppeType feldgruppeType = new FeldgruppeType(); + private final AntragsdatenType antragsdatenType = new AntragsdatenType(); @BeforeEach void init() { when(feldGruppeTypeCreator.create(vorgang)).thenReturn(feldgruppeType); + when(formDataMapper.toAntragsdatenType(any())).thenReturn(antragsdatenType); } @Test @@ -61,6 +69,20 @@ class AnwendungsspezifischeErweiterungTypeCreatorTest { assertThat(anwendungsspezifischeErweiterung.getFeldgruppe()).hasSize(1).first().isEqualTo(feldgruppeType); } + @Test + void shouldCallFormDataMapper() { + create(); + + verify(formDataMapper).toAntragsdatenType(vorgang); + } + + @Test + void shouldHaveAntragsdaten() { + var anwendungsspezifischeErweiterung = (OzgcloudErweiterungType) create(); + + assertThat(anwendungsspezifischeErweiterung.getAntragsdaten()).isNotNull(); + } + private AnwendungsspezifischeErweiterungType create() { return creator.create(vorgang); } diff --git a/alfa-xdomea/src/test/java/de/ozgcloud/alfa/vorgang/DatatypeMapperTest.java b/alfa-xdomea/src/test/java/de/ozgcloud/alfa/vorgang/DatatypeMapperTest.java new file mode 100644 index 0000000000000000000000000000000000000000..2fc79e9adf1c6d41b455c8baf7679b1c53435b9b --- /dev/null +++ b/alfa-xdomea/src/test/java/de/ozgcloud/alfa/vorgang/DatatypeMapperTest.java @@ -0,0 +1,89 @@ +package de.ozgcloud.alfa.vorgang; + +import static org.assertj.core.api.Assertions.*; + +import java.time.LocalDate; +import java.time.ZonedDateTime; +import java.util.List; + +import org.apache.commons.lang3.StringUtils; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.NullSource; +import org.junit.jupiter.params.provider.ValueSource; +import org.mockito.InjectMocks; + +import de.xoev.xdomea.DatatypeType; + +class DatatypeMapperTest { + + @InjectMocks + private DatatypeMapper datatypeMapper; + + @DisplayName("should return DatatypeType STRING when") + @ParameterizedTest(name = "\"{0}\"") + @NullSource + @ValueSource(strings = { StringUtils.EMPTY, "a" }) + void shouldReturnString(String arg) { + var datatype = datatypeMapper.from(arg); + + assertThat(datatype).isEqualTo(DatatypeType.STRING); + } + + @Test + void shouldReturnStringAsDefault() { + var datatype = datatypeMapper.from(new Object()); + + assertThat(datatype).isEqualTo(DatatypeType.STRING); + } + + @Test + void shouldReturnDate() { + var datatype = datatypeMapper.from(LocalDate.now()); + + assertThat(datatype).isEqualTo(DatatypeType.DATE); + } + + @Test + void shouldReturnDatetime() { + var datatype = datatypeMapper.from(ZonedDateTime.now()); + + assertThat(datatype).isEqualTo(DatatypeType.DATETIME); + } + + @Test + void shouldReturnInteger() { + var datatype = datatypeMapper.from(1); + + assertThat(datatype).isEqualTo(DatatypeType.INTEGER); + } + + @Test + void shouldReturnFloat() { + var datatype = datatypeMapper.from(1.0f); + + assertThat(datatype).isEqualTo(DatatypeType.FLOAT); + } + + @Test + void shouldReturnBoolean() { + var datatype = datatypeMapper.from(true); + + assertThat(datatype).isEqualTo(DatatypeType.BOOLEAN); + } + + @Test + void shouldReturnTypeOfElementsInCollection() { + var datatype = datatypeMapper.from(List.of(1, 2)); + + assertThat(datatype).isEqualTo(DatatypeType.INTEGER); + } + + @Test + void shouldReturnDefaultIfCollectionIsEmpty() { + var datatype = datatypeMapper.from(new Object[] {}); + + assertThat(datatype).isEqualTo(DatatypeType.STRING); + } +} \ No newline at end of file diff --git a/alfa-xdomea/src/test/java/de/ozgcloud/alfa/vorgang/ExportVorgangServiceITCase.java b/alfa-xdomea/src/test/java/de/ozgcloud/alfa/vorgang/ExportVorgangServiceITCase.java new file mode 100644 index 0000000000000000000000000000000000000000..636005eab233c90dc93f1f0ce352f3b59425adf9 --- /dev/null +++ b/alfa-xdomea/src/test/java/de/ozgcloud/alfa/vorgang/ExportVorgangServiceITCase.java @@ -0,0 +1,94 @@ +package de.ozgcloud.alfa.vorgang; + +import static de.ozgcloud.alfa.vorgang.AntragsdatenItemTypeTestFactory.*; +import static org.assertj.core.api.Assertions.*; + +import java.util.List; +import java.util.Map; + +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; + +import de.ozgcloud.common.test.ITCase; +import de.xoev.xdomea.AntragsdatenGroupType; +import de.xoev.xdomea.AntragsdatenItemType; +import de.xoev.xdomea.AntragsdatenSingleValueFieldType; +import de.xoev.xdomea.AntragsdatenType; +import de.xoev.xdomea.OzgcloudErweiterungType; + +@ITCase +class ExportVorgangServiceITCase { + + @Autowired + private ExportVorgangService exportVorgangService; + + @Nested + class TestMapVorgang { + + @Nested + class TestMapAntragsdaten { + + private static final Map<String, Object> FORM_DATA = Map.of( + KEY_STRING, VALUE_STRING, + KEY_MAP, Map.of(KEY_COLLECTION, List.of(VALUE_INTEGER)) + ); + + @Test + void shouldMapSingleField() { + var antragsdaten = mapToAntragsdaten(); + + assertThat(antragsdaten.getItem()).hasSize(2); + assertContainsSingleValueField(antragsdaten.getItem()); + } + + private void assertContainsSingleValueField(List<AntragsdatenItemType> items) { + var singleValueField = items.stream().filter(item -> item instanceof AntragsdatenSingleValueFieldType).findFirst(); + assertThat(singleValueField).isPresent().get().usingRecursiveComparison().isEqualTo(createSingleValueField()); + } + + @Test + void shouldMapGroup() { + var antragsdaten = mapToAntragsdaten(); + + assertThat(antragsdaten.getItem()).hasSize(2); + assertContainsGroup(antragsdaten.getItem()); + } + + private void assertContainsGroup(List<AntragsdatenItemType> items) { + var group = items.stream().filter(item -> item instanceof AntragsdatenGroupType).findFirst(); + assertThat(group).isPresent().get().extracting(AntragsdatenItemType::getName).isEqualTo(KEY_MAP); + } + + @Test + void shouldMapItemsInGroup() { + var antragsdaten = mapToAntragsdaten(); + + assertThat(antragsdaten.getItem()).hasSize(2); + assertContainsItemsInGroup(antragsdaten.getItem()); + } + + private void assertContainsItemsInGroup(List<AntragsdatenItemType> items) { + var groupItem = items.stream().filter(item -> item instanceof AntragsdatenGroupType) + .map(item -> ((AntragsdatenGroupType) item)) + .map(group -> group.getValue().getItem()) + .flatMap(List::stream).findFirst(); + assertThat(groupItem).isPresent().get().usingRecursiveComparison().isEqualTo(createMultiValueField()); + + } + + private AntragsdatenType mapToAntragsdaten() { + var erweiterungType = exportVorgangService.createVorgangType(buildVorgang()).getAnwendungsspezifischeErweiterung(); + + assertThat(erweiterungType).isOfAnyClassIn(OzgcloudErweiterungType.class); + return ((OzgcloudErweiterungType) erweiterungType).getAntragsdaten(); + } + + private VorgangWithEingang buildVorgang() { + var eingang = EingangTestFactory.createBuilder().formData(FORM_DATA).build(); + return VorgangWithEingangTestFactory.createBuilder().eingang(eingang).build(); + } + + } + } +} \ No newline at end of file diff --git a/alfa-xdomea/src/test/java/de/ozgcloud/alfa/vorgang/FormDataMapperTest.java b/alfa-xdomea/src/test/java/de/ozgcloud/alfa/vorgang/FormDataMapperTest.java new file mode 100644 index 0000000000000000000000000000000000000000..9cfb13a037e85443dc219724cd8821331231f66a --- /dev/null +++ b/alfa-xdomea/src/test/java/de/ozgcloud/alfa/vorgang/FormDataMapperTest.java @@ -0,0 +1,274 @@ +package de.ozgcloud.alfa.vorgang; + +import static org.assertj.core.api.Assertions.*; +import static org.mockito.ArgumentMatchers.*; +import static org.mockito.Mockito.*; + +import java.time.ZonedDateTime; +import java.util.Collections; +import java.util.List; +import java.util.Map; + +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.Spy; + +import de.ozgcloud.alfa.common.DateConverter; +import de.xoev.xdomea.AntragsdatenFieldType; +import de.xoev.xdomea.AntragsdatenGroupType; +import de.xoev.xdomea.AntragsdatenItemType; +import de.xoev.xdomea.AntragsdatenMultiValueFieldType; +import de.xoev.xdomea.AntragsdatenSingleValueFieldType; +import de.xoev.xdomea.DatatypeType; +import de.xoev.xdomea.ItemListType; + +class FormDataMapperTest { + + @Spy + @InjectMocks + private FormDataMapper formDataMapper; + + @Mock + private DatatypeMapper datatypeMapper; + @Mock + private DateConverter dateConverter; + + @Nested + class TestToAntragsdatenType { + + @Mock + private VorgangWithEingang vorgang; + + @Test + void shouldCallBuildItemType() { + doReturn(new Object()).when(formDataMapper).formatValue(any(), any()); + var vorgang = VorgangWithEingangTestFactory.create(); + + formDataMapper.toAntragsdatenType(vorgang); + + verify(formDataMapper).buileItemListType(vorgang.getEingang().getFormData()); + } + + @Test + void shouldMapEingangNull() { + var antragsdatenType = formDataMapper.toAntragsdatenType(vorgang); + + assertThat(antragsdatenType.getItem()).isEmpty(); + } + + @Test + void shouldMapFormDataNull() { + var eingang = mock(Eingang.class); + when(vorgang.getEingang()).thenReturn(eingang); + + var antragsdatenType = formDataMapper.toAntragsdatenType(vorgang); + + assertThat(antragsdatenType.getItem()).isEmpty(); + } + + } + + @Nested + class TestBuildItemListType { + + @Mock + private AntragsdatenItemType antragsdatenItemType1; + @Mock + private AntragsdatenItemType antragsdatenItemType2; + + @Test + void shouldAddItems() { + doReturn(List.of(antragsdatenItemType1, antragsdatenItemType2)).when(formDataMapper).buildItems(any()); + + var itemListType = formDataMapper.buileItemListType(EingangTestFactory.AS_MAP); + + assertThat(itemListType.getItem()).containsExactly(antragsdatenItemType1, antragsdatenItemType2); + } + } + + @Nested + class TestBuildItems { + @Mock + private AntragsdatenItemType expectedAntragsdatenItem; + + @Test + void shouldReturnEmptyList() { + var items = formDataMapper.buildItems(Collections.emptyMap()); + + assertThat(items).isEmpty(); + } + + @Test + void shoulAddSubmap() { + doReturn(expectedAntragsdatenItem).when(formDataMapper).buildAntragsdatenGroup(any(), any()); + + var items = formDataMapper.buildItems(Map.of("key", Map.of("key", "value"))); + + assertThat(items).hasSize(1).first().isEqualTo(expectedAntragsdatenItem); + } + + @Test + void shouldAddCollection() { + doReturn(expectedAntragsdatenItem).when(formDataMapper).buildMultiValueField(any(), any()); + + var items = formDataMapper.buildItems(Map.of("key", List.of("value"))); + + assertThat(items).hasSize(1).first().isEqualTo(expectedAntragsdatenItem); + } + + @Test + void shouldAddSingleValue() { + doReturn(expectedAntragsdatenItem).when(formDataMapper).buildSingleValueField(any(), any()); + + var items = formDataMapper.buildItems(Map.of("key", "value")); + + assertThat(items).hasSize(1).first().isEqualTo(expectedAntragsdatenItem); + } + } + + @Nested + class TestBuildAntragsdatenGroup { + + private static final String NAME = "name"; + private static final Map<String, Object> FORMDATA_SUBMAP = Map.of("key", "value"); + + @Mock + private ItemListType itemListType; + + @Test + void shouldSetName() { + doReturn(new Object()).when(formDataMapper).formatValue(any(), any()); + + var antragsdatenGroup = formDataMapper.buildAntragsdatenGroup(NAME, FORMDATA_SUBMAP); + + assertThat(antragsdatenGroup.getName()).isEqualTo(NAME); + } + + @Test + void shouldSetValue() { + doReturn(itemListType).when(formDataMapper).buileItemListType(any()); + + var antragsdatenGroup = (AntragsdatenGroupType) formDataMapper.buildAntragsdatenGroup(NAME, FORMDATA_SUBMAP); + + assertThat(antragsdatenGroup.getValue()).isEqualTo(itemListType); + } + + @Test + void shouldCallBuildItemListType() { + doReturn(new Object()).when(formDataMapper).formatValue(any(), any()); + + formDataMapper.buildAntragsdatenGroup(NAME, FORMDATA_SUBMAP); + + verify(formDataMapper).buileItemListType(FORMDATA_SUBMAP); + } + } + + @Nested + class TestBuildMultiValueField { + + private static final String NAME = "name"; + private static final List<String> FORMDATA_COLLECTION = List.of("value1"); + + @Test + void shouldSetName() { + when(datatypeMapper.from(any())).thenReturn(DatatypeType.STRING); + + var antragsdatenMultiValueFieldType = formDataMapper.buildMultiValueField(NAME, FORMDATA_COLLECTION); + + assertThat(antragsdatenMultiValueFieldType.getName()).isEqualTo(NAME); + } + + @Test + void shouldSetType() { + when(datatypeMapper.from(any())).thenReturn(DatatypeType.STRING); + + var antragsdatenMultiValueFieldType = (AntragsdatenFieldType) formDataMapper.buildMultiValueField(NAME, FORMDATA_COLLECTION); + + assertThat(antragsdatenMultiValueFieldType.getType()).isEqualTo(DatatypeType.STRING); + } + + @Test + void shouldSetValue() { + when(datatypeMapper.from(any())).thenReturn(DatatypeType.INTEGER); + var formData = List.of(1, 2); + + var antragsdatenMultiValueFieldType = (AntragsdatenMultiValueFieldType) formDataMapper.buildMultiValueField(NAME, formData); + + assertThat(antragsdatenMultiValueFieldType.getValue()).containsExactlyElementsOf(formData); + } + + @Test + void shouldCallFormatValue() { + when(datatypeMapper.from(any())).thenReturn(DatatypeType.STRING); + + formDataMapper.buildMultiValueField(NAME, FORMDATA_COLLECTION); + + verify(formDataMapper).formatValue(DatatypeType.STRING, FORMDATA_COLLECTION.get(0)); + } + } + + @Nested + class TestBuildSingleValueField { + + private static final String NAME = "name"; + private static final String FORMDATA_VALUE = "value"; + + @Test + void shouldSetName() { + doReturn(new Object()).when(formDataMapper).formatValue(any(), any()); + + var antragsdatenSingleValueFieldType = formDataMapper.buildSingleValueField(NAME, FORMDATA_VALUE); + + assertThat(antragsdatenSingleValueFieldType.getName()).isEqualTo(NAME); + } + + @Test + void shouldSetType() { + when(datatypeMapper.from(any())).thenReturn(DatatypeType.STRING); + + var antragsdatenSingleValueFieldType = (AntragsdatenFieldType) formDataMapper.buildSingleValueField(NAME, FORMDATA_VALUE); + + assertThat(antragsdatenSingleValueFieldType.getType()).isEqualTo(DatatypeType.STRING); + } + + @Test + void shouldSetValue() { + doReturn(FORMDATA_VALUE).when(formDataMapper).formatValue(any(), any()); + + var antragsdatenSingleValueFieldType = (AntragsdatenSingleValueFieldType) formDataMapper.buildSingleValueField(NAME, FORMDATA_VALUE); + + assertThat(antragsdatenSingleValueFieldType.getValue()).isEqualTo(FORMDATA_VALUE); + } + + @Test + void shouldCallFormatValue() { + when(datatypeMapper.from(any())).thenReturn(DatatypeType.STRING); + + formDataMapper.buildSingleValueField(NAME, FORMDATA_VALUE); + + verify(formDataMapper).formatValue(DatatypeType.STRING, FORMDATA_VALUE); + } + } + + @Nested + class TestFormatValue { + + @Test + void shouldFormatStringType() { + var value = formDataMapper.formatValue(DatatypeType.STRING, 1); + + assertThat(value).isEqualTo("1"); + } + + @Test + void shouldFormatDateTimeType() { + var dateTime = ZonedDateTime.now(); + + formDataMapper.formatValue(DatatypeType.DATETIME, dateTime); + + verify(dateConverter).toXmlGregorianCalendar(dateTime); + } + } +} \ No newline at end of file