From c2c170f3433e2cdadfa75ce685c92d37ff1bcb7c Mon Sep 17 00:00:00 2001 From: Jan Zickermann <jan.zickermann@dataport.de> Date: Thu, 26 Sep 2024 16:17:14 +0200 Subject: [PATCH] OZG-6754 KOP-2703 Validate zip file name --- .../xdomea/XdomeaXtaMessageCreator.java | 17 ++++- .../xdomea/reader/XdomeaValueReader.java | 2 + .../reader/XdomeaValueReaderFactory.java | 1 + .../client/xdomea/reader/XdomeaXmlValues.java | 1 + .../factory/XdomeaXmlValuesTestFactory.java | 3 +- .../xdomea/XdomeaXtaMessageCreatorTest.java | 71 +++++++++++++++++-- .../reader/XdomeaValueReaderFactoryTest.java | 5 ++ .../xdomea/reader/XdomeaValueReaderTest.java | 10 +++ 8 files changed, 103 insertions(+), 7 deletions(-) diff --git a/src/main/java/de/ozgcloud/xta/client/xdomea/XdomeaXtaMessageCreator.java b/src/main/java/de/ozgcloud/xta/client/xdomea/XdomeaXtaMessageCreator.java index 3bacbe6..cfbade2 100644 --- a/src/main/java/de/ozgcloud/xta/client/xdomea/XdomeaXtaMessageCreator.java +++ b/src/main/java/de/ozgcloud/xta/client/xdomea/XdomeaXtaMessageCreator.java @@ -42,12 +42,27 @@ public class XdomeaXtaMessageCreator { XtaMessageMetaData deriveMetaData(XtaFile xdomeaZipFile) throws ClientException { try { var xdomeaXmlValues = readXdomeaXmlValues(xdomeaZipFile); - return metadataMapper.mapXtaMessageMetadata(xdomeaXmlValues); + var messageMetadataData = metadataMapper.mapXtaMessageMetadata(xdomeaXmlValues); + validateZipFileName( + xdomeaZipFile.name(), + xdomeaXmlValues.processId(), + messageMetadataData.messageTypeCode() + ); + return messageMetadataData; } catch (TechnicalException e) { throw new ClientException("Failed to derive message metadata from xdomea document!", e); } } + void validateZipFileName(String xdomeaZipFileName, String processId, String messageTypeCode) throws ClientException { + var expectedXdomeaZipFileName = "%s_%s.zip".formatted(processId, messageTypeCode); + if (!expectedXdomeaZipFileName.equals(xdomeaZipFileName)) { + throw new ClientException( + "Expect xdomea zip file name to equal '%s'! (actual: '%s')".formatted(expectedXdomeaZipFileName, xdomeaZipFileName) + ); + } + } + XdomeaXmlValues readXdomeaXmlValues(XtaFile xdomeaZipFile) throws ClientException { var document = readXdomeaXmlDocument(xdomeaZipFile); return xdomeaValueReader.readValues(document); diff --git a/src/main/java/de/ozgcloud/xta/client/xdomea/reader/XdomeaValueReader.java b/src/main/java/de/ozgcloud/xta/client/xdomea/reader/XdomeaValueReader.java index 9df91a3..df4cff9 100644 --- a/src/main/java/de/ozgcloud/xta/client/xdomea/reader/XdomeaValueReader.java +++ b/src/main/java/de/ozgcloud/xta/client/xdomea/reader/XdomeaValueReader.java @@ -14,6 +14,7 @@ import lombok.RequiredArgsConstructor; @RequiredArgsConstructor public class XdomeaValueReader { + static final String PROCESS_ID_XPATH = getTextXpath("Kopf", "ProzessID"); static final String AUTHOR_ID_SUFFIX_XPATH = getTextXpath("Kopf", "Absender", "code"); static final String READER_ID_SUFFIX_XPATH = getTextXpath("Kopf", "Empfaenger", "code"); static final String MESSAGE_TYPE_ID_SUFFIX_XPATH = getTextXpath("Kopf", "Nachrichtentyp", "code"); @@ -29,6 +30,7 @@ public class XdomeaValueReader { public XdomeaXmlValues readValues(Document xdomeaXmlDocument) throws ClientException { return XdomeaXmlValues.builder() + .processId(readRequiredValue(xdomeaXmlDocument, PROCESS_ID_XPATH)) .messageTypeCode(readRequiredValue(xdomeaXmlDocument, MESSAGE_TYPE_ID_SUFFIX_XPATH)) .authorIdSuffix(readRequiredValue(xdomeaXmlDocument, AUTHOR_ID_SUFFIX_XPATH)) .readerIdSuffix(readRequiredValue(xdomeaXmlDocument, READER_ID_SUFFIX_XPATH)) diff --git a/src/main/java/de/ozgcloud/xta/client/xdomea/reader/XdomeaValueReaderFactory.java b/src/main/java/de/ozgcloud/xta/client/xdomea/reader/XdomeaValueReaderFactory.java index 1e9b6e0..569488d 100644 --- a/src/main/java/de/ozgcloud/xta/client/xdomea/reader/XdomeaValueReaderFactory.java +++ b/src/main/java/de/ozgcloud/xta/client/xdomea/reader/XdomeaValueReaderFactory.java @@ -30,6 +30,7 @@ public class XdomeaValueReaderFactory { public XdomeaValueReader create() { return XdomeaValueReader.builder() .xmlValueReaders(Stream.of( + PROCESS_ID_XPATH, MESSAGE_TYPE_ID_SUFFIX_XPATH, AUTHOR_ID_SUFFIX_XPATH, READER_ID_SUFFIX_XPATH diff --git a/src/main/java/de/ozgcloud/xta/client/xdomea/reader/XdomeaXmlValues.java b/src/main/java/de/ozgcloud/xta/client/xdomea/reader/XdomeaXmlValues.java index e5820e9..8f7ce94 100644 --- a/src/main/java/de/ozgcloud/xta/client/xdomea/reader/XdomeaXmlValues.java +++ b/src/main/java/de/ozgcloud/xta/client/xdomea/reader/XdomeaXmlValues.java @@ -6,6 +6,7 @@ import lombok.Builder; @Builder public record XdomeaXmlValues( + @NotBlank String processId, @NotBlank String messageTypeCode, @NotBlank String authorIdSuffix, @NotBlank String readerIdSuffix diff --git a/src/test/java/de/ozgcloud/xta/client/factory/XdomeaXmlValuesTestFactory.java b/src/test/java/de/ozgcloud/xta/client/factory/XdomeaXmlValuesTestFactory.java index 8e72d58..2c62293 100644 --- a/src/test/java/de/ozgcloud/xta/client/factory/XdomeaXmlValuesTestFactory.java +++ b/src/test/java/de/ozgcloud/xta/client/factory/XdomeaXmlValuesTestFactory.java @@ -4,7 +4,7 @@ import de.ozgcloud.xta.client.xdomea.reader.XdomeaXmlValues; public class XdomeaXmlValuesTestFactory { - + public static final String PROCESS_ID = "000ProcessId-111"; public static final String SHORT_MESSAGE_TYPE_CODE = "messageTypeCode"; public static final String AUTHOR_ID_SUFFIX = "authorIdSuffix"; public static final String READER_ID_SUFFIX = "readerIdSuffix"; @@ -15,6 +15,7 @@ public class XdomeaXmlValuesTestFactory { public static XdomeaXmlValues.XdomeaXmlValuesBuilder createBuilder() { return XdomeaXmlValues.builder() + .processId(PROCESS_ID) .messageTypeCode(SHORT_MESSAGE_TYPE_CODE) .authorIdSuffix(AUTHOR_ID_SUFFIX) .readerIdSuffix(READER_ID_SUFFIX); diff --git a/src/test/java/de/ozgcloud/xta/client/xdomea/XdomeaXtaMessageCreatorTest.java b/src/test/java/de/ozgcloud/xta/client/xdomea/XdomeaXtaMessageCreatorTest.java index e896b3b..969bbd6 100644 --- a/src/test/java/de/ozgcloud/xta/client/xdomea/XdomeaXtaMessageCreatorTest.java +++ b/src/test/java/de/ozgcloud/xta/client/xdomea/XdomeaXtaMessageCreatorTest.java @@ -1,5 +1,8 @@ package de.ozgcloud.xta.client.xdomea; +import static de.ozgcloud.xta.client.factory.MessageMetaDataTestFactory.*; +import static de.ozgcloud.xta.client.factory.XdomeaXmlValuesTestFactory.*; +import static de.ozgcloud.xta.client.factory.XtaFileTestFactory.*; import static org.assertj.core.api.Assertions.*; import static org.mockito.Mockito.*; @@ -14,6 +17,8 @@ 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.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.Spy; @@ -21,6 +26,9 @@ import org.w3c.dom.Document; import de.ozgcloud.common.errorhandling.TechnicalException; import de.ozgcloud.xta.client.exception.ClientException; +import de.ozgcloud.xta.client.factory.XdomeaXmlValuesTestFactory; +import de.ozgcloud.xta.client.factory.XtaFileTestFactory; +import de.ozgcloud.xta.client.factory.XtaMessageMetaDataTestFactory; import de.ozgcloud.xta.client.model.XtaFile; import de.ozgcloud.xta.client.model.XtaMessage; import de.ozgcloud.xta.client.model.XtaMessageMetaData; @@ -98,13 +106,10 @@ class XdomeaXtaMessageCreatorTest { @Nested class TestDeriveMetaData { - @Mock private XtaFile xdomeaZipFile; - @Mock private XdomeaXmlValues xdomeaXmlValues; - @Mock private XtaMessageMetaData metaData; @Mock @@ -113,6 +118,9 @@ class XdomeaXtaMessageCreatorTest { @BeforeEach @SneakyThrows void mock() { + xdomeaZipFile = XtaFileTestFactory.create(); + xdomeaXmlValues = XdomeaXmlValuesTestFactory.create(); + metaData = XtaMessageMetaDataTestFactory.create(); doReturn(xdomeaXmlValues).when(creator).readXdomeaXmlValues(xdomeaZipFile); } @@ -120,13 +128,38 @@ class XdomeaXtaMessageCreatorTest { @Test @SneakyThrows void shouldReturn() { - doReturn(metaData).when(metadataMapper).mapXtaMessageMetadata(xdomeaXmlValues); + mockValidMetadata(); var result = creator.deriveMetaData(xdomeaZipFile); assertThat(result).isEqualTo(metaData); } + @DisplayName("should verify zip file name") + @Test + @SneakyThrows + void shouldVerifyZipFileName() { + mockValidMetadata(); + + creator.deriveMetaData(xdomeaZipFile); + + verify(creator).validateZipFileName( + XTA_FILE_NAME, + PROCESS_ID, + MESSAGE_TYPE_CODE + ); + } + + @SneakyThrows + private void mockValidMetadata() { + doReturn(metaData).when(metadataMapper).mapXtaMessageMetadata(xdomeaXmlValues); + doNothing().when(creator).validateZipFileName( + any(), + any(), + any() + ); + } + @DisplayName("should throw client exception") @Test void shouldThrowClientException() { @@ -163,7 +196,6 @@ class XdomeaXtaMessageCreatorTest { assertThat(result).isEqualTo(xdomeaXmlValues); } - } @DisplayName("replace filename extension with xml") @@ -220,4 +252,33 @@ class XdomeaXtaMessageCreatorTest { } } + @DisplayName("validate zip file name") + @Nested + class TestValidateZipFileName { + + private static final String PROCESS_ID = "processId"; + private static final String MESSAGE_TYPE_CODE = "messageTypeCode"; + private static final String VALID_ZIP_FILE_NAME = "processId_messageTypeCode.zip"; + + @DisplayName("should not throw exception") + @Test + void shouldNotThrowException() { + assertThatCode(() -> creator.validateZipFileName(VALID_ZIP_FILE_NAME, PROCESS_ID, MESSAGE_TYPE_CODE)) + .doesNotThrowAnyException(); + } + + @DisplayName("should throw client exception") + @ParameterizedTest + @ValueSource(strings = { + "$processId_messageTypeCode.zip", + "processId_me$ssageTypeCode.zip", + "processId_messageTypeCode.zip$", + }) + void shouldThrowClientException() { + assertThatThrownBy(() -> creator.validateZipFileName("processId_messageTypeCode.zip", PROCESS_ID, "wrongMessageTypeCode")) + .isInstanceOf(ClientException.class); + } + + } + } \ No newline at end of file diff --git a/src/test/java/de/ozgcloud/xta/client/xdomea/reader/XdomeaValueReaderFactoryTest.java b/src/test/java/de/ozgcloud/xta/client/xdomea/reader/XdomeaValueReaderFactoryTest.java index b9ffaac..630e4bc 100644 --- a/src/test/java/de/ozgcloud/xta/client/xdomea/reader/XdomeaValueReaderFactoryTest.java +++ b/src/test/java/de/ozgcloud/xta/client/xdomea/reader/XdomeaValueReaderFactoryTest.java @@ -32,6 +32,9 @@ class XdomeaValueReaderFactoryTest { @Nested class TestCreate { + @Mock + XmlValueReader procesIdReader; + @Mock XmlValueReader messageTypeReader; @@ -45,6 +48,7 @@ class XdomeaValueReaderFactoryTest { @Test @SneakyThrows void shouldReturn() { + doReturn(procesIdReader).when(factory).createXmlValueReader(PROCESS_ID_XPATH); doReturn(messageTypeReader).when(factory).createXmlValueReader(MESSAGE_TYPE_ID_SUFFIX_XPATH); doReturn(authorIdReader).when(factory).createXmlValueReader(AUTHOR_ID_SUFFIX_XPATH); doReturn(readerIdReader).when(factory).createXmlValueReader(READER_ID_SUFFIX_XPATH); @@ -53,6 +57,7 @@ class XdomeaValueReaderFactoryTest { assertThat(reader).usingRecursiveComparison().isEqualTo(XdomeaValueReader.builder() .xmlValueReaders(Map.of( + PROCESS_ID_XPATH, procesIdReader, MESSAGE_TYPE_ID_SUFFIX_XPATH, messageTypeReader, AUTHOR_ID_SUFFIX_XPATH, authorIdReader, READER_ID_SUFFIX_XPATH, readerIdReader diff --git a/src/test/java/de/ozgcloud/xta/client/xdomea/reader/XdomeaValueReaderTest.java b/src/test/java/de/ozgcloud/xta/client/xdomea/reader/XdomeaValueReaderTest.java index ec4357b..99abcbe 100644 --- a/src/test/java/de/ozgcloud/xta/client/xdomea/reader/XdomeaValueReaderTest.java +++ b/src/test/java/de/ozgcloud/xta/client/xdomea/reader/XdomeaValueReaderTest.java @@ -33,6 +33,7 @@ class XdomeaValueReaderTest { @Nested class TestReadValues { + private static final String PROCESS_ID = "process id"; private static final String MESSAGE_TYPE_CODE = "message type code"; private static final String AUTHOR_ID_SUFFIX = "author id suffix"; private static final String READER_ID_SUFFIX = "reader id suffix"; @@ -43,11 +44,20 @@ class XdomeaValueReaderTest { @BeforeEach @SneakyThrows void mock() { + doReturn(PROCESS_ID).when(xdomeaValueReader).readRequiredValue(xdomeaXmlDocument, XdomeaValueReader.PROCESS_ID_XPATH); doReturn(MESSAGE_TYPE_CODE).when(xdomeaValueReader).readRequiredValue(xdomeaXmlDocument, XdomeaValueReader.MESSAGE_TYPE_ID_SUFFIX_XPATH); doReturn(AUTHOR_ID_SUFFIX).when(xdomeaValueReader).readRequiredValue(xdomeaXmlDocument, XdomeaValueReader.AUTHOR_ID_SUFFIX_XPATH); doReturn(READER_ID_SUFFIX).when(xdomeaValueReader).readRequiredValue(xdomeaXmlDocument, XdomeaValueReader.READER_ID_SUFFIX_XPATH); } + @DisplayName("should return process id") + @Test + void shouldReturnProcessId() { + var result = readValues(); + + assertThat(result.processId()).isEqualTo(PROCESS_ID); + } + @DisplayName("should return message type code") @Test void shouldReturnMessageTypeCode() { -- GitLab