diff --git a/src/main/java/de/ozgcloud/formcycle/formdata/FormStructureParser.java b/src/main/java/de/ozgcloud/formcycle/formdata/FormStructureParser.java index 7920ddda533aa93bc7659fc8a57825bf9064bc75..589ca3f994d61e783146be4eeff4843c9d10bb0a 100644 --- a/src/main/java/de/ozgcloud/formcycle/formdata/FormStructureParser.java +++ b/src/main/java/de/ozgcloud/formcycle/formdata/FormStructureParser.java @@ -11,6 +11,7 @@ import java.util.Objects; import java.util.Optional; import de.xima.fc.form.common.items.XItem; +import de.xima.fc.form.common.models.XPropertyValue; import lombok.RequiredArgsConstructor; @RequiredArgsConstructor @@ -28,27 +29,34 @@ class FormStructureParser { var xItem = entry.getValue(); var itemClass = ItemClass.fromString(xItem.getClassName()); if (isInputNode(itemClass)) { - addItem(xItem); + handleInputNode(xItem); } else if (isNestedContainer(itemClass)) { - containerNodes.push(addItem(xItem)); + handleContainerNode(xItem); } } return resultNodes; } - FormNode addItem(XItem xItem) { + void handleInputNode(XItem xItem) { + getResultNodes(xItem).add(buildNode(xItem)); + } + + void handleContainerNode(XItem xItem) { var formNode = buildNode(xItem); getResultNodes(xItem).add(formNode); - return formNode; + containerNodes.push(formNode); } FormNode buildNode(XItem xItem) { var formNode = FormNode.builder().itemId(xItem.getId()).name(xItem.getName()); - ItemClass.fromString(xItem.getClassName()).getTitleProperty().map(xItem::get) - .ifPresent(propertyValue -> formNode.title(propertyValue.getString())); + getTitle(xItem).ifPresent(formNode::title); return formNode.build(); } + Optional<String> getTitle(XItem xItem) { + return ItemClass.fromString(xItem.getClassName()).getTitleProperty().map(xItem::get).map(XPropertyValue::getString); + } + List<FormNode> getResultNodes(XItem xItem) { if (CONTAINER_NAME_ANTRAGSTELLER.equalsIgnoreCase(xItem.getName()) || containerNodes.isEmpty()) { return resultNodes; diff --git a/src/test/java/de/ozgcloud/formcycle/formdata/FormStructureParserITCase.java b/src/test/java/de/ozgcloud/formcycle/formdata/FormStructureParserITCase.java index 68e51fefe4226f28a4f8823191d2b43d58fcaa06..5efd169066f0e1a74979ff151efc1f592a915db4 100644 --- a/src/test/java/de/ozgcloud/formcycle/formdata/FormStructureParserITCase.java +++ b/src/test/java/de/ozgcloud/formcycle/formdata/FormStructureParserITCase.java @@ -26,9 +26,7 @@ package de.ozgcloud.formcycle.formdata; import static de.ozgcloud.formcycle.formdata.ItemClass.*; import static de.ozgcloud.formcycle.formdata.StructureMockFactory.*; import static org.assertj.core.api.Assertions.*; -import static org.mockito.Mockito.*; -import java.util.List; import java.util.Map; import org.junit.jupiter.api.Test; diff --git a/src/test/java/de/ozgcloud/formcycle/formdata/FormStructureParserTest.java b/src/test/java/de/ozgcloud/formcycle/formdata/FormStructureParserTest.java index 88448798a4215d5ffa0087dc8b6a81bc830b5c35..6d4fdc60282a6057172154d2bd8dd79689f16c5c 100644 --- a/src/test/java/de/ozgcloud/formcycle/formdata/FormStructureParserTest.java +++ b/src/test/java/de/ozgcloud/formcycle/formdata/FormStructureParserTest.java @@ -18,15 +18,12 @@ import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import org.mockito.InjectMocks; -import org.mockito.Spy; import de.xima.fc.form.common.items.XItem; import lombok.SneakyThrows; class FormStructureParserTest { - @Spy - @InjectMocks private FormStructureParser structureParser; @Nested @@ -43,23 +40,45 @@ class FormStructureParserTest { } @Test - void shouldCallAddItemWhenInputNode() { + void shouldCallIsInputNode() { + try (var itemClassMock = mockStatic(ItemClass.class)) { + var items = createItem(TEXT_FIELD); + + createParser(items).parse(); + + itemClassMock.verify(() -> ItemClass.isInputNode(TEXT_FIELD)); + } + + } + @Test + void shouldCallHandleInputNode() { var items = createItem(TEXT_FIELD); structureParser = spy(createParser(items)); structureParser.parse(); - verify(structureParser).addItem(items.get(ITEM_ID)); + verify(structureParser).handleInputNode(items.get(ITEM_ID)); } @Test - void shouldCallAddItemWhenContainerNode() { + void shouldCallIsNestedContainer() { + try (var itemClassMock = mockStatic(ItemClass.class)) { + var items = createItem(FIELD_SET); + + createParser(items).parse(); + + itemClassMock.verify(() -> ItemClass.isNestedContainer(FIELD_SET)); + } + } + + @Test + void shouldCallHandleContainerNode() { var items = createItem(FIELD_SET); structureParser = spy(createParser(items)); structureParser.parse(); - verify(structureParser).addItem(items.get(ITEM_ID)); + verify(structureParser).handleContainerNode(items.get(ITEM_ID)); } @Test @@ -80,13 +99,13 @@ class FormStructureParserTest { } @Nested - class TestAddItem { + class TestHandleInputNode { @Test void shouldCallGetResultNodes() { var xItem = getMock(TEXT_FIELD); - structureParser.addItem(xItem); + structureParser.handleInputNode(xItem); verify(structureParser).getResultNodes(xItem); } @@ -96,11 +115,50 @@ class FormStructureParserTest { var xItem = getMock(TEXT_FIELD); doReturn(new ArrayList<>()).when(structureParser).getResultNodes(any()); - structureParser.addItem(xItem); + structureParser.handleInputNode(xItem); + + verify(structureParser).buildNode(xItem); + } + + @Test + void shouldAddNodeToResultNodes() { + var resultNodes = new ArrayList<FormNode>(); + doReturn(resultNodes).when(structureParser).getResultNodes(any()); + var formNode = FormNodeTestFactory.create(); + doReturn(formNode).when(structureParser).buildNode(any()); + + structureParser.handleInputNode(getMock(TEXT_FIELD)); + + assertThat(resultNodes).containsExactly(formNode); + } + } + + @Nested + class TestHandleContainerNode { + + @BeforeEach + void init() { + structureParser = spy(new FormStructureParser(createItem(FIELD_SET))); + } + + @Test + void shouldCallBuildNode() { + var xItem = getMock(FIELD_SET); + + structureParser.handleContainerNode(xItem); verify(structureParser).buildNode(xItem); } + @Test + void shouldCallGetResultNodes() { + var xItem = getMock(FIELD_SET); + + structureParser.handleContainerNode(xItem); + + verify(structureParser).getResultNodes(xItem); + } + @Test void shouldAddNodeToResultNodes() { var resultNodes = new ArrayList<FormNode>(); @@ -108,19 +166,30 @@ class FormStructureParserTest { var formNode = FormNodeTestFactory.create(); doReturn(formNode).when(structureParser).buildNode(any()); - structureParser.addItem(getMock(TEXT_FIELD)); + structureParser.handleContainerNode(getMock(FIELD_SET)); assertThat(resultNodes).containsExactly(formNode); } @Test - void shouldReturnBuiltNode() { + void shouldAddNodeToTopOfContainerNodes() { var formNode = FormNodeTestFactory.create(); doReturn(formNode).when(structureParser).buildNode(any()); + var parentNode = injectContainerNodes(); + var fieldSetMock = getMock(FIELD_SET); + when(fieldSetMock.getParentId()).thenReturn(parentNode.getFirst().getItemId()); - var result = structureParser.addItem(getMock(TEXT_FIELD)); + structureParser.handleContainerNode(fieldSetMock); + + assertThat(getContainerNodes()).first().isSameAs(formNode); + } - assertThat(result).isSameAs(formNode); + @SuppressWarnings("unchecked") + @SneakyThrows + private Deque<FormNode> getContainerNodes() { + var containerNodesField = FormStructureParser.class.getDeclaredField("containerNodes"); + containerNodesField.setAccessible(true); + return (Deque<FormNode>) containerNodesField.get(structureParser); } }