diff --git a/archive-manager-server/src/main/java/de/ozgcloud/archive/common/xta/XtaFileHelper.java b/archive-manager-server/src/main/java/de/ozgcloud/archive/common/xta/XtaFileHelper.java index 1957b3c905eb41277079be3184be7e102239eb15..d87b3af517e29b4184ebd805d0d0546125e5ff16 100644 --- a/archive-manager-server/src/main/java/de/ozgcloud/archive/common/xta/XtaFileHelper.java +++ b/archive-manager-server/src/main/java/de/ozgcloud/archive/common/xta/XtaFileHelper.java @@ -5,7 +5,7 @@ import org.springframework.stereotype.Component; import de.ozgcloud.xta.client.model.XtaFile; @Component -class XtaFileHelper { +public class XtaFileHelper { public XtaImportConfirmationHandler initImportConfirmationHandler(XtaFile file) { return XtaImportConfirmationHandler.initFrom(file); diff --git a/archive-manager-server/src/main/java/de/ozgcloud/archive/common/xta/XtaFileXmlUtils.java b/archive-manager-server/src/main/java/de/ozgcloud/archive/common/xta/XtaFileXmlUtils.java index 0b158ac03a4442bca4e56240bf84f6500606b026..8f446a0fe20819907b908b950fa90c9c65ba6df5 100644 --- a/archive-manager-server/src/main/java/de/ozgcloud/archive/common/xta/XtaFileXmlUtils.java +++ b/archive-manager-server/src/main/java/de/ozgcloud/archive/common/xta/XtaFileXmlUtils.java @@ -21,7 +21,7 @@ import lombok.extern.log4j.Log4j2; @Log4j2 @NoArgsConstructor(access = AccessLevel.PRIVATE) -class XtaFileXmlUtils { +public class XtaFileXmlUtils { public static boolean isType(XtaFile file, XtaFileType type) { try { @@ -33,6 +33,10 @@ class XtaFileXmlUtils { } } + private static String getRootTagName(Document doc) { + return doc.getDocumentElement().getTagName(); + } + static Document parse(XtaFile file) throws SAXException, IOException, ParserConfigurationException { var document = XtaFileXmlUtils.createDocumentBuilder().parse(file.content().getDataSource().getInputStream()); document.getDocumentElement().normalize(); @@ -43,10 +47,6 @@ class XtaFileXmlUtils { return DocumentBuilderFactory.newDefaultInstance().newDocumentBuilder(); } - private static String getRootTagName(Document doc) { - return doc.getDocumentElement().getTagName(); - } - public static <T> T read(XtaFile xtaFile, Class<T> clazz) { try { return XtaFileXmlUtils.unmarshalContent(xtaFile, JAXBContext.newInstance(clazz).createUnmarshaller()); diff --git a/archive-manager-server/src/main/java/de/ozgcloud/archive/common/xta/XtaImportConfirmationHandler.java b/archive-manager-server/src/main/java/de/ozgcloud/archive/common/xta/XtaImportConfirmationHandler.java index 425a7570fcbea29f267521cce3b92c2423f097d4..d286cbbfc1b5bf06a0d1d9d84fbaef3bd88778d3 100644 --- a/archive-manager-server/src/main/java/de/ozgcloud/archive/common/xta/XtaImportConfirmationHandler.java +++ b/archive-manager-server/src/main/java/de/ozgcloud/archive/common/xta/XtaImportConfirmationHandler.java @@ -9,7 +9,7 @@ import de.xoev.xdomea.ErfolgOderMisserfolgAbgabeType; import lombok.Getter; import lombok.RequiredArgsConstructor; -class XtaImportConfirmationHandler { +public class XtaImportConfirmationHandler { @Getter private final AbgabeImportBestaetigen0402 importConfirmation; @@ -27,7 +27,7 @@ class XtaImportConfirmationHandler { } @RequiredArgsConstructor - static class XtaAbgabeHandler { + public static class XtaAbgabeHandler { private final ErfolgOderMisserfolgAbgabeType abgabeType; diff --git a/archive-manager-server/src/main/java/de/ozgcloud/archive/common/xta/XtaService.java b/archive-manager-server/src/main/java/de/ozgcloud/archive/common/xta/XtaService.java index cd81d8529d2fbcbcf34ba702b68d35d86508090c..9c7af3c1eee6c0bfd18b3c8bc114fb81cd07aab1 100644 --- a/archive-manager-server/src/main/java/de/ozgcloud/archive/common/xta/XtaService.java +++ b/archive-manager-server/src/main/java/de/ozgcloud/archive/common/xta/XtaService.java @@ -1,19 +1,10 @@ package de.ozgcloud.archive.common.xta; -import java.util.List; import java.util.Optional; +import java.util.function.Consumer; -import org.apache.commons.collections.CollectionUtils; -import org.springframework.context.ApplicationEventPublisher; import org.springframework.stereotype.Service; -import de.ozgcloud.archive.common.command.ArchiveManagerCommand; -import de.ozgcloud.archive.common.command.CommandOrder; -import de.ozgcloud.archive.common.command.CommandService; -import de.ozgcloud.archive.common.xta.XtaImportConfirmationHandler.XtaAbgabeHandler; -import de.ozgcloud.command.Command; -import de.ozgcloud.command.CommandExecutedEvent; -import de.ozgcloud.command.CommandFailedEvent; import de.ozgcloud.common.errorhandling.TechnicalException; import de.ozgcloud.xta.client.XtaClient; import de.ozgcloud.xta.client.exception.XtaClientException; @@ -30,11 +21,6 @@ public class XtaService { private static final String XTA_CLIENT_IS_NOT_CONFIGURED_MESSAGE = "XtaClient is not configured! Cannot send message to DMS."; private final Optional<XtaClient> xtaClient; - private final XtaFileHelper xtaFileHelper; - - private final CommandService commandService; - - private final ApplicationEventPublisher eventPublisher; public void sendXdomeaFile(XtaFile xdomeaFile) { try { @@ -56,55 +42,12 @@ public class XtaService { return xtaClient.orElseThrow(() -> new TechnicalException(XTA_CLIENT_IS_NOT_CONFIGURED_MESSAGE)); } - public void fetchMessages() { + public void fetchMessages(Consumer<XtaMessage> messageConsumer) { try { - getXtaClient().fetchMessages(this::consumeMessage); + getXtaClient().fetchMessages(messageConsumer); } catch (XtaClientException e) { throw new TechnicalException("Error fetching xta messages.", e); } } - void consumeMessage(XtaMessage message) { - if (isImportConfirmation(message.messageFile())) { - xtaFileHelper.initImportConfirmationHandler(message.messageFile()).getAbgaben().forEach(this::handleAbgabe); - } - } - - boolean isImportConfirmation(XtaFile xtaFile) { - return XtaFileXmlUtils.isType(xtaFile, XtaFileType.IMPORT_CONFIRMATION); - } - - void handleAbgabe(XtaAbgabeHandler abgabeHandler) { - var vorgangId = abgabeHandler.getVorgangId(); - var pendingCommands = findPendingArchiveVorgangCommands(vorgangId); - - if (CollectionUtils.isNotEmpty(pendingCommands)) { - evaluateAbgabe(abgabeHandler, pendingCommands); - } else { - LOG.warn("No pending archive command found for vorgang: %s.", vorgangId); - } - } - - private List<ArchiveManagerCommand> findPendingArchiveVorgangCommands(String vorgangId) { - return commandService.findPending(vorgangId, CommandOrder.ARCHIVE_VORGANG).toList(); - } - - void evaluateAbgabe(XtaAbgabeHandler abgabeHandler, List<ArchiveManagerCommand> pendingCommands) { - if (pendingCommands.size() > 1) { - LOG.warn("Multiple pending commands found for vorgang: %s.", abgabeHandler.getVorgangId()); - } - if (abgabeHandler.isSuccessfullyDone()) { - pendingCommands.forEach(this::publishCommandExecutedEvent); - } else { - pendingCommands.forEach(command -> publishCommandFailedEvent(abgabeHandler, command)); - } - } - - void publishCommandExecutedEvent(Command pendingCommand) { - eventPublisher.publishEvent(new CommandExecutedEvent(pendingCommand)); - } - - void publishCommandFailedEvent(XtaAbgabeHandler contentHandler, Command pendingCommand) { - eventPublisher.publishEvent(new CommandFailedEvent(pendingCommand.getId(), contentHandler.getFehlermeldung())); - } } diff --git a/archive-manager-server/src/main/java/de/ozgcloud/archive/common/xta/XtaMessageScheduler.java b/archive-manager-server/src/main/java/de/ozgcloud/archive/quittung/QuittungScheduler.java similarity index 78% rename from archive-manager-server/src/main/java/de/ozgcloud/archive/common/xta/XtaMessageScheduler.java rename to archive-manager-server/src/main/java/de/ozgcloud/archive/quittung/QuittungScheduler.java index d9ecc15b65c88b78f2337061aac9d4f7cc1be93f..25a235654b45b8d934b83a011a8a5174932a3251 100644 --- a/archive-manager-server/src/main/java/de/ozgcloud/archive/common/xta/XtaMessageScheduler.java +++ b/archive-manager-server/src/main/java/de/ozgcloud/archive/quittung/QuittungScheduler.java @@ -1,4 +1,4 @@ -package de.ozgcloud.archive.common.xta; +package de.ozgcloud.archive.quittung; import jakarta.annotation.PostConstruct; @@ -11,11 +11,11 @@ import lombok.RequiredArgsConstructor; @Component @Profile("!itcase") @RequiredArgsConstructor -public class XtaMessageScheduler { +public class QuittungScheduler { private static final String SCHEDULER_CRON = "#{xtaProperties.schedulerCron}"; - private final XtaService service; + private final QuittungService service; @PostConstruct public void onStartup() { @@ -24,6 +24,6 @@ public class XtaMessageScheduler { @Scheduled(cron = SCHEDULER_CRON) public void run() { - service.fetchMessages(); + service.fetchQuittung(); } } diff --git a/archive-manager-server/src/main/java/de/ozgcloud/archive/quittung/QuittungService.java b/archive-manager-server/src/main/java/de/ozgcloud/archive/quittung/QuittungService.java new file mode 100644 index 0000000000000000000000000000000000000000..0b3486004a39c1501026b22f64d3d409ba293e59 --- /dev/null +++ b/archive-manager-server/src/main/java/de/ozgcloud/archive/quittung/QuittungService.java @@ -0,0 +1,84 @@ +package de.ozgcloud.archive.quittung; + +import java.util.List; + +import org.apache.commons.collections.CollectionUtils; +import org.springframework.context.ApplicationEventPublisher; +import org.springframework.stereotype.Service; + +import de.ozgcloud.archive.common.command.ArchiveManagerCommand; +import de.ozgcloud.archive.common.command.CommandOrder; +import de.ozgcloud.archive.common.command.CommandService; +import de.ozgcloud.archive.common.xta.XtaFileHelper; +import de.ozgcloud.archive.common.xta.XtaFileType; +import de.ozgcloud.archive.common.xta.XtaFileXmlUtils; +import de.ozgcloud.archive.common.xta.XtaImportConfirmationHandler.XtaAbgabeHandler; +import de.ozgcloud.archive.common.xta.XtaService; +import de.ozgcloud.command.Command; +import de.ozgcloud.command.CommandExecutedEvent; +import de.ozgcloud.command.CommandFailedEvent; +import de.ozgcloud.xta.client.model.XtaFile; +import de.ozgcloud.xta.client.model.XtaMessage; +import lombok.RequiredArgsConstructor; +import lombok.extern.log4j.Log4j2; + +@Log4j2 +@RequiredArgsConstructor +@Service +class QuittungService { + + private final XtaService xtaService; + private final XtaFileHelper xtaFileHelper; + + private final CommandService commandService; + + private final ApplicationEventPublisher eventPublisher; + + public void fetchQuittung() { + xtaService.fetchMessages(this::consumeQuittung); + } + + void consumeQuittung(XtaMessage message) { + if (isImportConfirmation(message.messageFile())) { + xtaFileHelper.initImportConfirmationHandler(message.messageFile()).getAbgaben().forEach(this::handleAbgabe); + } + } + + boolean isImportConfirmation(XtaFile xtaFile) { + return XtaFileXmlUtils.isType(xtaFile, XtaFileType.IMPORT_CONFIRMATION); + } + + void handleAbgabe(XtaAbgabeHandler abgabeHandler) { + var vorgangId = abgabeHandler.getVorgangId(); + var pendingCommands = findPendingArchiveVorgangCommands(vorgangId); + + if (CollectionUtils.isNotEmpty(pendingCommands)) { + evaluateAbgabe(abgabeHandler, pendingCommands); + } else { + LOG.warn("No pending archive command found for vorgang: %s.", vorgangId); + } + } + + private List<ArchiveManagerCommand> findPendingArchiveVorgangCommands(String vorgangId) { + return commandService.findPending(vorgangId, CommandOrder.ARCHIVE_VORGANG).toList(); + } + + void evaluateAbgabe(XtaAbgabeHandler abgabeHandler, List<ArchiveManagerCommand> pendingCommands) { + if (pendingCommands.size() > 1) { + LOG.warn("Multiple pending commands found for vorgang: %s.", abgabeHandler.getVorgangId()); + } + if (abgabeHandler.isSuccessfullyDone()) { + pendingCommands.forEach(this::publishCommandExecutedEvent); + } else { + pendingCommands.forEach(command -> publishCommandFailedEvent(abgabeHandler, command)); + } + } + + void publishCommandExecutedEvent(Command pendingCommand) { + eventPublisher.publishEvent(new CommandExecutedEvent(pendingCommand)); + } + + void publishCommandFailedEvent(XtaAbgabeHandler contentHandler, Command pendingCommand) { + eventPublisher.publishEvent(new CommandFailedEvent(pendingCommand.getId(), contentHandler.getFehlermeldung())); + } +} diff --git a/archive-manager-server/src/test/java/de/ozgcloud/archive/common/xta/AbgabeImportBestaetigen0402TestFactory.java b/archive-manager-server/src/test/java/de/ozgcloud/archive/common/xta/AbgabeImportBestaetigen0402TestFactory.java index de3c8ca0a071d6d3d0bb40f244659142c966fad2..1b7e8be653f0d5b7d46473310006f4e64c3d2f69 100644 --- a/archive-manager-server/src/test/java/de/ozgcloud/archive/common/xta/AbgabeImportBestaetigen0402TestFactory.java +++ b/archive-manager-server/src/test/java/de/ozgcloud/archive/common/xta/AbgabeImportBestaetigen0402TestFactory.java @@ -1,8 +1,11 @@ package de.ozgcloud.archive.common.xta; +import jakarta.xml.bind.JAXBContext; +import jakarta.xml.bind.JAXBException; +import jakarta.xml.bind.Unmarshaller; + import org.w3c.dom.Document; -import de.ozgcloud.archive.common.xta.XtaFileXmlUtils; import de.xoev.xdomea.AbgabeImportBestaetigen0402; import lombok.SneakyThrows; @@ -14,8 +17,14 @@ public class AbgabeImportBestaetigen0402TestFactory { public static final String FILE_PATH = "xml-templates/21b2f942-c454-44e6-a706-c4f6ef2d584a_Abgabe.ImportBestaetigen.0402.xml"; + @SneakyThrows public static AbgabeImportBestaetigen0402 create() { - return XtaFileXmlUtils.read(XtaFileTestFactory.create(AbgabeImportBestaetigen0402TestFactory.FILE_PATH), AbgabeImportBestaetigen0402.class); + return (AbgabeImportBestaetigen0402) getUnmarshaller() + .unmarshal(XtaFileTestFactory.create(AbgabeImportBestaetigen0402TestFactory.FILE_PATH).content().getInputStream()); + } + + private static Unmarshaller getUnmarshaller() throws JAXBException { + return JAXBContext.newInstance(AbgabeImportBestaetigen0402.class).createUnmarshaller(); } @SneakyThrows diff --git a/archive-manager-server/src/test/java/de/ozgcloud/archive/common/xta/XtaFileTestFactory.java b/archive-manager-server/src/test/java/de/ozgcloud/archive/common/xta/XtaFileTestFactory.java index 3f5bea53c7bceafa4d6994e428279f5b4b000d50..35183dd9596733ce0d852458863f3a8b8ff1b6bd 100644 --- a/archive-manager-server/src/test/java/de/ozgcloud/archive/common/xta/XtaFileTestFactory.java +++ b/archive-manager-server/src/test/java/de/ozgcloud/archive/common/xta/XtaFileTestFactory.java @@ -10,7 +10,7 @@ import lombok.SneakyThrows; public class XtaFileTestFactory { - private static final String DUMMY_XML_FILE_PATH = "xml-templates/dummy.xml";; + private static final String DUMMY_XML_FILE_PATH = "xml-templates/dummy.xml"; public static XtaFile create() { return create(DUMMY_XML_FILE_PATH); diff --git a/archive-manager-server/src/test/java/de/ozgcloud/archive/common/xta/XtaServiceTest.java b/archive-manager-server/src/test/java/de/ozgcloud/archive/common/xta/XtaServiceTest.java index 52c803ae7dcdef08876e1942e6614845fb4ab768..8aa6c075b216996913d946da156958c7db6f0dae 100644 --- a/archive-manager-server/src/test/java/de/ozgcloud/archive/common/xta/XtaServiceTest.java +++ b/archive-manager-server/src/test/java/de/ozgcloud/archive/common/xta/XtaServiceTest.java @@ -5,32 +5,22 @@ import static org.junit.jupiter.api.Assertions.*; import static org.mockito.ArgumentMatchers.*; import static org.mockito.Mockito.*; -import java.util.List; import java.util.Optional; -import java.util.stream.Stream; +import java.util.function.Consumer; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; -import org.mockito.ArgumentCaptor; -import org.mockito.Captor; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.MockedStatic; import org.mockito.Spy; import org.springframework.context.ApplicationEventPublisher; -import de.ozgcloud.archive.common.command.ArchiveManagerCommand; -import de.ozgcloud.archive.common.command.CommandOrder; import de.ozgcloud.archive.common.command.CommandService; -import de.ozgcloud.archive.common.command.CommandTestFactory; -import de.ozgcloud.archive.common.xta.XtaImportConfirmationHandler.XtaAbgabeHandler; -import de.ozgcloud.archive.vorgang.VorgangWithEingangTestFactory; import de.ozgcloud.archive.vorgang.XdomeaXtaFileTestFactory; -import de.ozgcloud.command.CommandExecutedEvent; -import de.ozgcloud.command.CommandFailedEvent; import de.ozgcloud.common.errorhandling.TechnicalException; import de.ozgcloud.xta.client.XtaClient; import de.ozgcloud.xta.client.exception.XtaClientException; @@ -48,13 +38,6 @@ class XtaServiceTest { @Mock private XtaClient xtaClient; - @Mock - private CommandService commandService; - @Mock - private ApplicationEventPublisher eventPublisher; - @Mock - private XtaFileHelper xtaFileHelper; - @Nested class TestSendXdomeaFile { @@ -183,7 +166,7 @@ class XtaServiceTest { @BeforeEach void givenXtaClientConfigured() { - xtaService = spy(new XtaService(Optional.of(xtaClient), xtaFileHelper, commandService, eventPublisher)); + xtaService = spy(new XtaService(Optional.of(xtaClient))); } @Test @@ -200,7 +183,7 @@ class XtaServiceTest { @BeforeEach void givenXtaClientNotConfigured() { - xtaService = spy(new XtaService(Optional.empty(), xtaFileHelper, commandService, eventPublisher)); + xtaService = spy(new XtaService(Optional.empty())); } @Test @@ -218,219 +201,40 @@ class XtaServiceTest { @Nested class TestFetchMessages { - @BeforeEach - void mock() { - doReturn(xtaClient).when(service).getXtaClient(); - } - - @SneakyThrows - @Test - void shouldCallClient() { - service.fetchMessages(); - - verify(xtaClient).fetchMessages(any()); - } - - @SneakyThrows - @Test - void shouldThrowException() { - when(xtaClient.fetchMessages(any())).thenThrow(new XtaClientException("error-message")); - - assertThatThrownBy(() -> service.fetchMessages()).isInstanceOf(TechnicalException.class); - } - } - - @DisplayName("Consume message") - @Nested - class TestConsumeMessage { - - @Mock - private XtaImportConfirmationHandler xtaFileContentHandler; - - private final XtaMessage xtaMessage = XtaMessageTestFactory.create(); - - @Test - void shouldCallIsImportConfirmation() { - service.consumeMessage(xtaMessage); - - verify(service).isImportConfirmation(XtaMessageTestFactory.MESSAGE_FILE); - } - - @DisplayName("on import confirmation") - @Nested - class TestOnImportConfirmation { - - @Mock - private XtaAbgabeHandler abgabeHandler; - - @BeforeEach - void mock() { - doReturn(true).when(service).isImportConfirmation(any()); - when(xtaFileHelper.initImportConfirmationHandler(any())).thenReturn(xtaFileContentHandler); - when(xtaFileContentHandler.getAbgaben()).thenReturn(Stream.of(abgabeHandler, abgabeHandler)); - doNothing().when(service).handleAbgabe(any()); - } - - @Test - void shouldInitContentHandler() { - service.consumeMessage(xtaMessage); - - verify(xtaFileHelper).initImportConfirmationHandler(XtaMessageTestFactory.MESSAGE_FILE); - } - - @DisplayName("should handle import confirmation if type from document is matching") - @Test - void shouldCallHandleAbgabe() { - service.consumeMessage(xtaMessage); - - verify(service, times(2)).handleAbgabe(abgabeHandler); - } - } - - @DisplayName("should not handle message if its not an import confirmation") - @Test - void shouldNotProceed() { - doReturn(false).when(service).isImportConfirmation(any()); - - service.consumeMessage(xtaMessage); - - verify(service, never()).handleAbgabe(any()); - verify(xtaFileHelper, never()).initImportConfirmationHandler(any()); - } - } - - @DisplayName("Handle abgabe") - @Nested - class TestHandleAbgabe { - @Mock - private XtaAbgabeHandler abgabeHandler; + private Consumer<XtaMessage> messageConsumer; @BeforeEach void mock() { - when(abgabeHandler.getVorgangId()).thenReturn(VorgangWithEingangTestFactory.ID); - when(commandService.findPending(any(), any())).thenReturn(Stream.empty()); + doReturn(xtaClient).when(service).getXtaClient(); } @Test - void shouldGetVorgangId() { - handleImportConfirmation(); + void shouldCallGetXtaClient() { + fetchMessages(); - verify(abgabeHandler).getVorgangId(); + verify(service).getXtaClient(); } + @SneakyThrows @Test - void shouldCallCommandService() { - handleImportConfirmation(); - - verify(commandService).findPending(VorgangWithEingangTestFactory.ID, CommandOrder.ARCHIVE_VORGANG); - } - - @DisplayName("on existing pending commands") - @Nested - class TestOnExistingPendingCommands { - - private final ArchiveManagerCommand command = CommandTestFactory.create(); - private final List<ArchiveManagerCommand> commands = List.of(command); - - @BeforeEach - void mock() { - when(commandService.findPending(any(), any())).thenReturn(commands.stream()); - doNothing().when(service).evaluateAbgabe(any(), any()); - } - - @Test - void shouldCallEvaluateConfirmation() { - handleImportConfirmation(); + void shouldCallClient() { + fetchMessages(); - verify(service).evaluateAbgabe(abgabeHandler, commands); - } + verify(xtaClient).fetchMessages(messageConsumer); } + @SneakyThrows @Test - void shouldNotCallEvaluateImportConfirmationOnEmptyList() { - handleImportConfirmation(); + void shouldThrowException() { + when(xtaClient.fetchMessages(any())).thenThrow(new XtaClientException("error-message")); - verify(service, never()).evaluateAbgabe(any(), any()); + assertThatThrownBy(this::fetchMessages).isInstanceOf(TechnicalException.class); } - private void handleImportConfirmation() { - service.handleAbgabe(abgabeHandler); + private void fetchMessages() { + service.fetchMessages(messageConsumer); } } - @DisplayName("Evaluate abgabe") - @Nested - class TestEvaluateConfirmation { - - @Mock - private XtaAbgabeHandler abgabeHandler; - - private final ArchiveManagerCommand command = CommandTestFactory.create(); - private final List<ArchiveManagerCommand> commands = List.of(command, command); - - @Test - void shouldCallIsSuccessfullyDone() { - service.evaluateAbgabe(abgabeHandler, commands); - - verify(abgabeHandler).isSuccessfullyDone(); - } - - @Test - void shouldCallPublishCommendExcecutedEvent() { - when(abgabeHandler.isSuccessfullyDone()).thenReturn(true); - - service.evaluateAbgabe(abgabeHandler, commands); - - verify(service, times(2)).publishCommandExecutedEvent(command); - } - - @Test - void shouldCallPublishCommandFailedEvent() { - when(abgabeHandler.isSuccessfullyDone()).thenReturn(false); - - service.evaluateAbgabe(abgabeHandler, commands); - - verify(service, times(2)).publishCommandFailedEvent(abgabeHandler, command); - } - - @DisplayName("on successfully done import confirmation") - @Nested - class TestPublishCommandExcutedEvent { - - @Captor - private ArgumentCaptor<CommandExecutedEvent> commandExecutedEventCaptor; - - @DisplayName("should publish command executed event") - @Test - void shouldPublishCommandExecutedEvent() { - service.publishCommandExecutedEvent(command); - - verify(eventPublisher).publishEvent(commandExecutedEventCaptor.capture()); - assertThat(commandExecutedEventCaptor.getValue().getCommand()).isEqualTo(command); - } - } - - @DisplayName("on failed import confirmation") - @Nested - class TestPublishCommandFailedEvent { - - @Captor - private ArgumentCaptor<CommandFailedEvent> commandFailedEventCaptor; - - private final ArchiveManagerCommand command = CommandTestFactory.create(); - - @DisplayName("should publish command failed event") - @Test - void shouldPublishCommandFailedEvent() { - when(abgabeHandler.getFehlermeldung()).thenReturn(AbgabeImportBestaetigen0402TestFactory.FEHLERMELDUNG); - - service.publishCommandFailedEvent(abgabeHandler, command); - - verify(eventPublisher).publishEvent(commandFailedEventCaptor.capture()); - assertThat(commandFailedEventCaptor.getValue().getSource()).isEqualTo(CommandTestFactory.ID); - assertThat(commandFailedEventCaptor.getValue().getErrorMessage()).isEqualTo(AbgabeImportBestaetigen0402TestFactory.FEHLERMELDUNG); - } - } - } } diff --git a/archive-manager-server/src/test/java/de/ozgcloud/archive/common/xta/XtaMessageSchedulerTest.java b/archive-manager-server/src/test/java/de/ozgcloud/archive/quittung/QuittungSchedulerTest.java similarity index 60% rename from archive-manager-server/src/test/java/de/ozgcloud/archive/common/xta/XtaMessageSchedulerTest.java rename to archive-manager-server/src/test/java/de/ozgcloud/archive/quittung/QuittungSchedulerTest.java index f8c91f14a71d6e7e2d1d296ebcbb664fe00d8940..120451f8f879100ad73f8e32f25581ecd94d4cf1 100644 --- a/archive-manager-server/src/test/java/de/ozgcloud/archive/common/xta/XtaMessageSchedulerTest.java +++ b/archive-manager-server/src/test/java/de/ozgcloud/archive/quittung/QuittungSchedulerTest.java @@ -1,4 +1,4 @@ -package de.ozgcloud.archive.common.xta; +package de.ozgcloud.archive.quittung; import static org.mockito.Mockito.*; @@ -8,16 +8,13 @@ import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.Spy; -import de.ozgcloud.archive.common.xta.XtaMessageScheduler; -import de.ozgcloud.archive.common.xta.XtaService; - -class XtaMessageSchedulerTest { +class QuittungSchedulerTest { @Spy @InjectMocks - private XtaMessageScheduler scheduler; + private QuittungScheduler scheduler; @Mock - private XtaService service; + private QuittungService service; @Nested class TestOnStartup { @@ -37,7 +34,7 @@ class XtaMessageSchedulerTest { void shouldCallService() { scheduler.run(); - verify(service).fetchMessages(); + verify(service).fetchQuittung(); } } } \ No newline at end of file diff --git a/archive-manager-server/src/test/java/de/ozgcloud/archive/quittung/QuittungServiceTest.java b/archive-manager-server/src/test/java/de/ozgcloud/archive/quittung/QuittungServiceTest.java new file mode 100644 index 0000000000000000000000000000000000000000..a0494f18a387e72c159b632e649285191fa65b97 --- /dev/null +++ b/archive-manager-server/src/test/java/de/ozgcloud/archive/quittung/QuittungServiceTest.java @@ -0,0 +1,269 @@ +package de.ozgcloud.archive.quittung; + +import static org.assertj.core.api.Assertions.*; +import static org.mockito.ArgumentMatchers.*; +import static org.mockito.Mockito.*; + +import java.util.List; +import java.util.function.Consumer; +import java.util.stream.Stream; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.mockito.ArgumentCaptor; +import org.mockito.Captor; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.Spy; +import org.springframework.context.ApplicationEventPublisher; + +import de.ozgcloud.archive.common.command.ArchiveManagerCommand; +import de.ozgcloud.archive.common.command.CommandOrder; +import de.ozgcloud.archive.common.command.CommandService; +import de.ozgcloud.archive.common.command.CommandTestFactory; +import de.ozgcloud.archive.common.xta.AbgabeImportBestaetigen0402TestFactory; +import de.ozgcloud.archive.common.xta.XtaFileHelper; +import de.ozgcloud.archive.common.xta.XtaImportConfirmationHandler; +import de.ozgcloud.archive.common.xta.XtaImportConfirmationHandler.XtaAbgabeHandler; +import de.ozgcloud.archive.common.xta.XtaMessageTestFactory; +import de.ozgcloud.archive.common.xta.XtaService; +import de.ozgcloud.archive.vorgang.VorgangWithEingangTestFactory; +import de.ozgcloud.command.CommandExecutedEvent; +import de.ozgcloud.command.CommandFailedEvent; +import de.ozgcloud.xta.client.model.XtaMessage; + +class QuittungServiceTest { + + @Spy + @InjectMocks + private QuittungService service; + @Mock + private XtaService xtaService; + @Mock + private CommandService commandService; + @Mock + private ApplicationEventPublisher eventPublisher; + @Mock + private XtaFileHelper xtaFileHelper; + + @Nested + class TestFetchQuittung { + + @Captor + private ArgumentCaptor<Consumer<XtaMessage>> consumerCaptor; + + private final XtaMessage message = XtaMessageTestFactory.create(); + + @Test + void shouldCallXtaService() { + service.fetchQuittung(); + + verify(xtaService).fetchMessages(any()); + } + + @Test + void shouldPassQuittungConsumerToXtaService() { + service.fetchQuittung(); + + verify(xtaService).fetchMessages(consumerCaptor.capture()); + consumerCaptor.getValue().accept(message); + verify(service).consumeQuittung(message); + } + } + + @DisplayName("Consume message") + @Nested + class TestConsumeQuittung { + + @Mock + private XtaImportConfirmationHandler xtaFileContentHandler; + + private final XtaMessage xtaMessage = XtaMessageTestFactory.create(); + + @Test + void shouldCallIsImportConfirmation() { + service.consumeQuittung(xtaMessage); + + verify(service).isImportConfirmation(XtaMessageTestFactory.MESSAGE_FILE); + } + + @DisplayName("on import confirmation") + @Nested + class TestOnImportConfirmation { + + @Mock + private XtaAbgabeHandler abgabeHandler; + + @BeforeEach + void mock() { + doReturn(true).when(service).isImportConfirmation(any()); + when(xtaFileHelper.initImportConfirmationHandler(any())).thenReturn(xtaFileContentHandler); + when(xtaFileContentHandler.getAbgaben()).thenReturn(Stream.of(abgabeHandler, abgabeHandler)); + doNothing().when(service).handleAbgabe(any()); + } + + @Test + void shouldInitContentHandler() { + service.consumeQuittung(xtaMessage); + + verify(xtaFileHelper).initImportConfirmationHandler(XtaMessageTestFactory.MESSAGE_FILE); + } + + @DisplayName("should handle import confirmation if type from document is matching") + @Test + void shouldCallHandleAbgabe() { + service.consumeQuittung(xtaMessage); + + verify(service, times(2)).handleAbgabe(abgabeHandler); + } + } + + @DisplayName("should not handle message if its not an import confirmation") + @Test + void shouldNotProceed() { + doReturn(false).when(service).isImportConfirmation(any()); + + service.consumeQuittung(xtaMessage); + + verify(service, never()).handleAbgabe(any()); + verify(xtaFileHelper, never()).initImportConfirmationHandler(any()); + } + } + + @DisplayName("Handle abgabe") + @Nested + class TestHandleAbgabe { + + @Mock + private XtaAbgabeHandler abgabeHandler; + + @BeforeEach + void mock() { + when(abgabeHandler.getVorgangId()).thenReturn(VorgangWithEingangTestFactory.ID); + when(commandService.findPending(any(), any())).thenReturn(Stream.empty()); + } + + @Test + void shouldGetVorgangId() { + handleImportConfirmation(); + + verify(abgabeHandler).getVorgangId(); + } + + @Test + void shouldCallCommandService() { + handleImportConfirmation(); + + verify(commandService).findPending(VorgangWithEingangTestFactory.ID, CommandOrder.ARCHIVE_VORGANG); + } + + @DisplayName("on existing pending commands") + @Nested + class TestOnExistingPendingCommands { + + private final ArchiveManagerCommand command = CommandTestFactory.create(); + private final List<ArchiveManagerCommand> commands = List.of(command); + + @BeforeEach + void mock() { + when(commandService.findPending(any(), any())).thenReturn(commands.stream()); + doNothing().when(service).evaluateAbgabe(any(), any()); + } + + @Test + void shouldCallEvaluateConfirmation() { + handleImportConfirmation(); + + verify(service).evaluateAbgabe(abgabeHandler, commands); + } + } + + @Test + void shouldNotCallEvaluateImportConfirmationOnEmptyList() { + handleImportConfirmation(); + + verify(service, never()).evaluateAbgabe(any(), any()); + } + + private void handleImportConfirmation() { + service.handleAbgabe(abgabeHandler); + } + } + + @DisplayName("Evaluate abgabe") + @Nested + class TestEvaluateConfirmation { + + @Mock + private XtaAbgabeHandler abgabeHandler; + + private final ArchiveManagerCommand command = CommandTestFactory.create(); + private final List<ArchiveManagerCommand> commands = List.of(command, command); + + @Test + void shouldCallIsSuccessfullyDone() { + service.evaluateAbgabe(abgabeHandler, commands); + + verify(abgabeHandler).isSuccessfullyDone(); + } + + @Test + void shouldCallPublishCommendExcecutedEvent() { + when(abgabeHandler.isSuccessfullyDone()).thenReturn(true); + + service.evaluateAbgabe(abgabeHandler, commands); + + verify(service, times(2)).publishCommandExecutedEvent(command); + } + + @Test + void shouldCallPublishCommandFailedEvent() { + when(abgabeHandler.isSuccessfullyDone()).thenReturn(false); + + service.evaluateAbgabe(abgabeHandler, commands); + + verify(service, times(2)).publishCommandFailedEvent(abgabeHandler, command); + } + + @DisplayName("on successfully done import confirmation") + @Nested + class TestPublishCommandExcutedEvent { + + @Captor + private ArgumentCaptor<CommandExecutedEvent> commandExecutedEventCaptor; + + @DisplayName("should publish command executed event") + @Test + void shouldPublishCommandExecutedEvent() { + service.publishCommandExecutedEvent(command); + + verify(eventPublisher).publishEvent(commandExecutedEventCaptor.capture()); + assertThat(commandExecutedEventCaptor.getValue().getCommand()).isEqualTo(command); + } + } + + @DisplayName("on failed import confirmation") + @Nested + class TestPublishCommandFailedEvent { + + @Captor + private ArgumentCaptor<CommandFailedEvent> commandFailedEventCaptor; + + private final ArchiveManagerCommand command = CommandTestFactory.create(); + + @DisplayName("should publish command failed event") + @Test + void shouldPublishCommandFailedEvent() { + when(abgabeHandler.getFehlermeldung()).thenReturn(AbgabeImportBestaetigen0402TestFactory.FEHLERMELDUNG); + + service.publishCommandFailedEvent(abgabeHandler, command); + + verify(eventPublisher).publishEvent(commandFailedEventCaptor.capture()); + assertThat(commandFailedEventCaptor.getValue().getSource()).isEqualTo(CommandTestFactory.ID); + assertThat(commandFailedEventCaptor.getValue().getErrorMessage()).isEqualTo(AbgabeImportBestaetigen0402TestFactory.FEHLERMELDUNG); + } + } + } +}