diff --git a/src/main/java/de/ozgcloud/formcycle/OzgPluginExecutor.java b/src/main/java/de/ozgcloud/formcycle/OzgPluginExecutor.java index d3c47d1512242c40d7aa496c774867c8a3348522..a7b0ab2d1c3be9d2d10555bc2c591e0e4ee2d22d 100644 --- a/src/main/java/de/ozgcloud/formcycle/OzgPluginExecutor.java +++ b/src/main/java/de/ozgcloud/formcycle/OzgPluginExecutor.java @@ -22,20 +22,16 @@ */ package de.ozgcloud.formcycle; -import java.util.ArrayList; -import java.util.EnumMap; import java.util.List; -import java.util.Map; -import java.util.Optional; -import java.util.Set; +import java.util.function.Predicate; import java.util.function.Supplier; +import java.util.stream.Collectors; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import de.ozgcloud.eingang.formcycle.FormCycleConfirmationResponse; import de.ozgcloud.formcycle.attachment.AttachmentMapper; -import de.ozgcloud.formcycle.attachment.AttachmentType; import de.ozgcloud.formcycle.attachment.FormcycleAttachment; import de.ozgcloud.formcycle.errorhandling.OzgPluginSoftError; import de.ozgcloud.formcycle.errorhandling.Warning; @@ -58,32 +54,17 @@ public final class OzgPluginExecutor { public ExecutionResult execute() { LOG.debug("Executing plugin WorkflowElementNodePlugin"); - var formData = addAttachedFiles(pluginFormDataAdapter.readFormData()); + var formData = addRepresentations(pluginFormDataAdapter.readFormData()); + formData = addAttachments(formData); return buildExecutionResult(sendFormData(formData), formData); } - FormData addAttachedFiles(FormData formData) { - var formDataBuilder = formData.toBuilder(); - var attachedFiles = getAttachedFiles(formData.getAttachmentUuids()); - Optional.ofNullable(attachedFiles.get(AttachmentType.REPRESENTATION)).ifPresentOrElse(formDataBuilder::representations, - () -> formDataBuilder.warning(buildMissingRepresentationsWarning(formData.getRequestId()))); - if (!formData.getAttachmentUuids().isEmpty()) { - Optional.ofNullable(attachedFiles.get(AttachmentType.ATTACHMENT)).ifPresentOrElse(formDataBuilder::attachments, - () -> formDataBuilder.warning(buildMissingAttachmentsWarning(formData.getRequestId()))); + FormData addRepresentations(FormData formData) { + var representations = getAttachedFiles(attachmentUuid -> !formData.getAttachmentUuids().contains(attachmentUuid)); + if (representations.isEmpty()) { + return formData.toBuilder().warning(buildMissingRepresentationsWarning(formData.getRequestId())).build(); } - return formDataBuilder.build(); - } - - Map<AttachmentType, List<FormcycleAttachment>> getAttachedFiles(Set<String> uploadFieldUuids) { - var resultMap = new EnumMap<AttachmentType, List<FormcycleAttachment>>(AttachmentType.class); - for (Attachment attachment : attachmentsSupplier.get()) { - if (uploadFieldUuids.contains(attachment.getUUID())) { - resultMap.computeIfAbsent(AttachmentType.ATTACHMENT, e -> new ArrayList<>()).add(attachmentMapper.map(attachment)); - continue; - } - resultMap.computeIfAbsent(AttachmentType.REPRESENTATION, e -> new ArrayList<>()).add(attachmentMapper.map(attachment)); - } - return resultMap; + return formData.toBuilder().representations(representations).build(); } Warning buildMissingRepresentationsWarning(String requestId) { @@ -92,6 +73,22 @@ public final class OzgPluginExecutor { requestId)); } + FormData addAttachments(FormData formData) { + if (formData.getAttachmentUuids().isEmpty()) { + return formData; + } + var attachments = getAttachedFiles(formData.getAttachmentUuids()::contains); + if (attachments.isEmpty()) { + return formData.toBuilder().warning(buildMissingAttachmentsWarning(formData.getRequestId())).build(); + } + return formData.toBuilder().attachments(attachments).build(); + } + + List<FormcycleAttachment> getAttachedFiles(Predicate<String> attachmentUuidFilter) { + return attachmentsSupplier.get().stream().filter(attachment -> attachmentUuidFilter.test(attachment.getUUID())).map(attachmentMapper::map) + .collect(Collectors.toList()); + } + Warning buildMissingAttachmentsWarning(String requestId) { return buildWarning(OzgPluginSoftError.MISSING_ATTACHMENTS, String.format("Attachments uploaded in the form were not included in the form data. (RequestId: %s)", requestId)); diff --git a/src/test/java/de/ozgcloud/formcycle/OzgPluginExecutorTest.java b/src/test/java/de/ozgcloud/formcycle/OzgPluginExecutorTest.java index 1e0b561e24714761e875b74eebfbb143809599e6..6b0269def717eff88ad3b6852107350171ab72de 100644 --- a/src/test/java/de/ozgcloud/formcycle/OzgPluginExecutorTest.java +++ b/src/test/java/de/ozgcloud/formcycle/OzgPluginExecutorTest.java @@ -30,6 +30,8 @@ import java.util.Collections; import java.util.List; import java.util.Map; import java.util.Set; +import java.util.UUID; +import java.util.function.Predicate; import java.util.function.Supplier; import org.junit.jupiter.api.BeforeEach; @@ -45,7 +47,6 @@ import org.mockito.Spy; import de.ozgcloud.eingang.formcycle.FormCycleConfirmationResponse; import de.ozgcloud.eingang.formcycle.FormCycleFormData; import de.ozgcloud.formcycle.attachment.AttachmentMapper; -import de.ozgcloud.formcycle.attachment.AttachmentType; import de.ozgcloud.formcycle.attachment.FormcycleAttachment; import de.ozgcloud.formcycle.attachment.FormcycleAttachmentTestFactory; import de.ozgcloud.formcycle.errorhandling.NodeThrewExceptionFactory; @@ -88,13 +89,18 @@ class OzgPluginExecutorTest { private FormCycleConfirmationResponse response; @Mock private ExecutionResult executionResult; + @Mock + private FormData formDataWithRepresentations; + @Mock + private FormData formDataWithAttachments; @SneakyThrows @BeforeEach void setup() { when(ozgHttpClient.send(any(), any(), any())).thenReturn(response); when(pluginFormDataAdapter.readFormData()).thenReturn(FORM_DATA); - doReturn(FORM_DATA).when(executor).addAttachedFiles(any()); + doReturn(formDataWithRepresentations).when(executor).addRepresentations(any()); + doReturn(formDataWithAttachments).when(executor).addAttachments(any()); doReturn(executionResult).when(executor).buildExecutionResult(any(), any()); } @@ -106,24 +112,31 @@ class OzgPluginExecutorTest { } @Test - void shouldCallAddAttachedFiles() { + void shouldCallAddRepresentations() { + executor.execute(); + + verify(executor).addRepresentations(FORM_DATA); + } + + @Test + void shouldCallAddAttachments() { executor.execute(); - verify(executor).addAttachedFiles(FORM_DATA); + verify(executor).addAttachments(formDataWithRepresentations); } @Test void shouldCallSendFormData() { executor.execute(); - verify(executor).sendFormData(FORM_DATA); + verify(executor).sendFormData(formDataWithAttachments); } @Test void shouldCallBuildExecutionResult() { executor.execute(); - verify(executor).buildExecutionResult(response, FORM_DATA); + verify(executor).buildExecutionResult(response, formDataWithAttachments); } @Test @@ -135,141 +148,143 @@ class OzgPluginExecutorTest { } @Nested - class TestAddAttachedFiles { + class TestAddRepresentations { + + @Mock + private Warning warning; @Captor - private ArgumentCaptor<Set<String>> attachmentUuidsCapture; + private ArgumentCaptor<Predicate<String>> filterPredicateCapture; - private final FormData formData = FormDataTestFactory.createBuilder().clearAttachments().clearRepresentations().clearWarnings().build(); + private final FormData formData = FormDataTestFactory.createBuilder().clearRepresentations().build(); @Test void shouldCallGetAttachedFiles() { - mockGetAttachedFiles(); + doReturn(List.of(FormcycleAttachmentTestFactory.create())).when(executor).getAttachedFiles(any()); - executor.addAttachedFiles(formData); + executor.addRepresentations(formData); - verify(executor).getAttachedFiles(attachmentUuidsCapture.capture()); - assertThat(attachmentUuidsCapture.getValue()).containsExactly(FormDataTestFactory.ATTACHMENT_UUID); + verify(executor).getAttachedFiles(filterPredicateCapture.capture()); + assertThat(filterPredicateCapture.getValue().test(FormDataTestFactory.ATTACHMENT_UUID)).isFalse(); } @Test void shouldSetRepresentations() { - mockGetAttachedFiles(); + var representation = FormcycleAttachmentTestFactory.create(); + doReturn(List.of(representation)).when(executor).getAttachedFiles(any()); - var result = executor.addAttachedFiles(formData); + var result = executor.addRepresentations(formData); - assertThat(result.getRepresentations()).hasSize(1).first().extracting("uuid").isEqualTo(FormDataTestFactory.REPRESENTATION_UUID); + assertThat(result.getRepresentations()).hasSize(1).first().isEqualTo(representation); } @Test - void shouldSetAttachments() { - mockGetAttachedFiles(); + void shouldNotAddAnyWarnings() { + doReturn(List.of(FormcycleAttachmentTestFactory.create())).when(executor).getAttachedFiles(any()); - var result = executor.addAttachedFiles(formData); + var result = executor.addRepresentations(FormDataTestFactory.createBuilder().clearWarnings().build()); - assertThat(result.getAttachments()).hasSize(1).first().extracting("uuid").isEqualTo(FormDataTestFactory.ATTACHMENT_UUID); + assertThat(result.getWarnings()).isEmpty(); } @Test - void shouldNotAddAnyWarnings() { - mockGetAttachedFiles(); + void shouldCallBuildMissingRepresentationsWarning() { + doReturn(Collections.emptyList()).when(executor).getAttachedFiles(any()); + doReturn(warning).when(executor).buildMissingRepresentationsWarning(any()); - var result = executor.addAttachedFiles(formData); + executor.addRepresentations(formData); - assertThat(result.getWarnings()).isEmpty(); + verify(executor).buildMissingRepresentationsWarning(formData.getRequestId()); } @Test - void shouldNotAddMissingAttachmentWarning() { - var attachedFiles = Map.of( - AttachmentType.REPRESENTATION, - List.of(FormcycleAttachmentTestFactory.createBuilder().uuid(FormDataTestFactory.REPRESENTATION_UUID).build())); - doReturn(attachedFiles).when(executor).getAttachedFiles(any()); + void shouldAddWhenMissingRepresentations() { + doReturn(Collections.emptyList()).when(executor).getAttachedFiles(any()); + doReturn(warning).when(executor).buildMissingRepresentationsWarning(any()); - var result = executor.addAttachedFiles(formData.toBuilder().clearAttachmentUuids().build()); + var result = executor.addRepresentations(formData); - assertThat(result.getWarnings()).isEmpty(); + assertThat(result.getWarnings()).hasSize(1).first().isSameAs(warning); } - private void mockGetAttachedFiles() { - var attachedFiles = Map.of( - AttachmentType.ATTACHMENT, - List.of(FormcycleAttachmentTestFactory.createBuilder().uuid(FormDataTestFactory.ATTACHMENT_UUID).build()), - AttachmentType.REPRESENTATION, - List.of(FormcycleAttachmentTestFactory.createBuilder().uuid(FormDataTestFactory.REPRESENTATION_UUID).build())); - doReturn(attachedFiles).when(executor).getAttachedFiles(any()); - } + } - @Nested - class TestAddWarnings { + @Nested + class TestAddAttachments { - @Mock - private Warning warning; + @Mock + private Warning warning; - @Test - void shouldCallBuildMissingRepresentationsWarning() { - doReturn(Map.of(AttachmentType.ATTACHMENT, List.of(FormcycleAttachmentTestFactory.create()))).when(executor).getAttachedFiles(any()); + @Captor + private ArgumentCaptor<Set<String>> attachmentUuidsCapture; + @Captor + private ArgumentCaptor<Predicate<String>> filterPredicateCapture; - executor.addAttachedFiles(formData); + private FormData formData = FormDataTestFactory.createBuilder().clearAttachments().build(); - verify(executor).buildMissingRepresentationsWarning(formData.getRequestId()); - } + @Test + void shouldReturnSameWhenNoAttachmentUuids() { + var expectedFormData = FormDataTestFactory.createBuilder().clearAttachmentUuids().build(); - @Test - void shouldAddWhenMissingRepresentations() { - doReturn(Map.of(AttachmentType.ATTACHMENT, List.of(FormcycleAttachmentTestFactory.create()))).when(executor).getAttachedFiles(any()); - doReturn(warning).when(executor).buildMissingRepresentationsWarning(any()); + var result = executor.addAttachments(expectedFormData); - var result = executor.addAttachedFiles(formData); + assertThat(result).isSameAs(expectedFormData); + } - assertThat(result.getWarnings()).hasSize(1).first().isSameAs(warning); - } + @Test + void shouldCallGetAttachedFiles() { + doReturn(List.of(FormcycleAttachmentTestFactory.create())).when(executor).getAttachedFiles(any()); - @Test - void shouldAddNotAddRepresentations() { - doReturn(Map.of(AttachmentType.ATTACHMENT, List.of(FormcycleAttachmentTestFactory.create()))).when(executor).getAttachedFiles(any()); + executor.addAttachments(formData); - var result = executor.addAttachedFiles(formData); + verify(executor).getAttachedFiles(filterPredicateCapture.capture()); + assertThat(filterPredicateCapture.getValue().test(FormDataTestFactory.ATTACHMENT_UUID)).isTrue(); + } - assertThat(result.getRepresentations()).isEmpty(); - } + @Test + void shouldSetAttachments() { + var representation = FormcycleAttachmentTestFactory.create(); + doReturn(List.of(representation)).when(executor).getAttachedFiles(any()); - @Test - void shouldCallBuildMissingAttachmentsWarning() { - doReturn(Map.of(AttachmentType.REPRESENTATION, List.of(FormcycleAttachmentTestFactory.create()))).when(executor) - .getAttachedFiles(any()); + var result = executor.addAttachments(formData); - executor.addAttachedFiles(formData); + assertThat(result.getAttachments()).hasSize(1).first().isEqualTo(representation); + } - verify(executor).buildMissingAttachmentsWarning(formData.getRequestId()); - } + @Test + void shouldNotAddAnyWarnings() { + doReturn(List.of(FormcycleAttachmentTestFactory.create())).when(executor).getAttachedFiles(any()); + + var result = executor.addAttachments(FormDataTestFactory.createBuilder().clearWarnings().build()); + + assertThat(result.getWarnings()).isEmpty(); + } - @Test - void shouldAddWhenMissingAttachments() { - doReturn(Map.of(AttachmentType.REPRESENTATION, List.of(FormcycleAttachmentTestFactory.create()))).when(executor) - .getAttachedFiles(any()); - doReturn(warning).when(executor).buildMissingAttachmentsWarning(any()); + @Test + void shouldCallBuildMissingAttachmentsWarning() { + doReturn(Collections.emptyList()).when(executor).getAttachedFiles(any()); + doReturn(warning).when(executor).buildMissingAttachmentsWarning(any()); - var result = executor.addAttachedFiles(formData); + executor.addAttachments(formData); - assertThat(result.getWarnings()).hasSize(1).first().isSameAs(warning); - } + verify(executor).buildMissingAttachmentsWarning(formData.getRequestId()); + } - @Test - void shouldNotAddAttachments() { - doReturn(Map.of(AttachmentType.REPRESENTATION, List.of(FormcycleAttachmentTestFactory.create()))).when(executor) - .getAttachedFiles(any()); + @Test + void shouldAddWhenMissingAttachments() { + doReturn(Collections.emptyList()).when(executor).getAttachedFiles(any()); + doReturn(warning).when(executor).buildMissingAttachmentsWarning(any()); - var result = executor.addAttachedFiles(formData); + var result = executor.addAttachments(formData); - assertThat(result.getAttachments()).isEmpty(); - } + assertThat(result.getWarnings()).hasSize(1).first().isSameAs(warning); } + } @Nested @DisplayName("Attachment's handling") - class TestGetAttachments { + class TestGetAttachedFiles { @Mock private Attachment attachment; @@ -280,44 +295,32 @@ class OzgPluginExecutorTest { void shouldReturnEmpty() { when(attachmentSupplier.get()).thenReturn(Collections.emptyList()); - var attachedFiles = getAttachedFiles(Collections.emptySet()); + var attachedFiles = executor.getAttachedFiles(uuid -> true); assertThat(attachedFiles).isEmpty(); } @Test - void shouldGetAttachments() { - var expectedAttachment = initAttachment(attachment); - - var attachedFiles = getAttachedFiles(Set.of(FormcycleAttachmentTestFactory.UUID)); - - assertThat(attachedFiles).hasSize(1).containsOnly(Map.entry(AttachmentType.ATTACHMENT, List.of(expectedAttachment))); - } - - @Test - void shouldGetRepresentations() { - var expectedAttachment = initAttachment(representation); + void shouldCallMapper() { + initAttachment(); - var attachedFiles = getAttachedFiles(Set.of(FormcycleAttachmentTestFactory.UUID)); + executor.getAttachedFiles(uuid -> true); - assertThat(attachedFiles).hasSize(1).containsOnly(Map.entry(AttachmentType.ATTACHMENT, List.of(expectedAttachment))); + verify(attachmentMapper).map(attachment); } @Test - @DisplayName("should return all attachments as representations when no upload fields") - @SneakyThrows - void shouldGetAllRepresentations() { - when(attachmentMapper.map(any())).thenAnswer(invocation -> mock(FormcycleAttachment.class)); - when(attachmentSupplier.get()).thenReturn(List.of(attachment, representation)); + void shouldApplyFilterAndReturnAttachments() { + var expectedAttachment = initAttachment(); + when(representation.getUUID()).thenReturn(UUID.randomUUID().toString()); + when(attachmentSupplier.get()).thenReturn(List.of(representation, attachment)); - var attachedFiles = getAttachedFiles(Collections.emptySet()); + var attachedFiles = executor.getAttachedFiles(FormcycleAttachmentTestFactory.UUID::equals); - assertThat(attachedFiles).hasSize(1); - assertThat(attachedFiles.get(AttachmentType.REPRESENTATION)).hasSize(2); + assertThat(attachedFiles).hasSize(1).containsExactly(expectedAttachment); } - @SneakyThrows - private FormcycleAttachment initAttachment(Attachment attachment) { + private FormcycleAttachment initAttachment() { var expectedAttachment = FormcycleAttachmentTestFactory.create(); when(attachmentMapper.map(any())).thenReturn(expectedAttachment); when(attachment.getUUID()).thenReturn(FormcycleAttachmentTestFactory.UUID); @@ -325,10 +328,6 @@ class OzgPluginExecutorTest { return expectedAttachment; } - @SneakyThrows - private Map<AttachmentType, List<FormcycleAttachment>> getAttachedFiles(Set<String> ids) { - return executor.getAttachedFiles(ids); - } } @Nested