Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found
Select Git revision

Target

Select target project
  • ozg-cloud/app/eingang/xta-adapter
1 result
Select Git revision
Show changes
Commits on Source (2)
Showing
with 732 additions and 413 deletions
package de.ozgcloud.eingang.fim;
import java.util.List;
import org.springframework.stereotype.Component;
import de.ozgcloud.eingang.common.formdata.IncomingFile;
import de.ozgcloud.eingang.common.formdata.IncomingFileGroup;
import de.ozgcloud.eingang.xta.EingangRepresentationsAndAttachments;
import de.ozgcloud.eingang.xta.XtaIncomingFilesMapper;
import de.ozgcloud.xta.client.model.XtaFile;
import de.ozgcloud.xta.client.model.XtaMessage;
import lombok.RequiredArgsConstructor;
import lombok.extern.log4j.Log4j2;
@Component
@RequiredArgsConstructor
@Log4j2
public class FimMessageDataMapper {
private final XtaIncomingFilesMapper xtaIncomingFilesMapper;
static final String FIM_ATTACHMENT_GROUP_NAME = "sonstige";
public EingangRepresentationsAndAttachments mapEingangRepresentationsAndAttachments(XtaMessage message) {
return EingangRepresentationsAndAttachments.builder()
.primaryFormDataFileName(message.messageFile().name())
.primaryFormDataPdfFileName("")
.representations(getRepresentations(message))
.attachments(getAttachmentGroups(message))
.build();
}
List<IncomingFile> getRepresentations(XtaMessage message) {
return List.of(xtaIncomingFilesMapper.toIncomingFile(message.messageFile()));
}
List<IncomingFileGroup> getAttachmentGroups(XtaMessage msg) {
var attachments = getAttachments(msg.attachmentFiles());
return attachments.isEmpty()
? List.of()
: List.of(
IncomingFileGroup.builder()
.name(FIM_ATTACHMENT_GROUP_NAME)
.files(attachments)
.build()
);
}
private List<IncomingFile> getAttachments(List<XtaFile> attachmentFiles) {
return attachmentFiles.stream()
.map(xtaIncomingFilesMapper::toIncomingFile)
.toList();
}
}
......@@ -35,6 +35,9 @@ import de.ozgcloud.eingang.common.errorhandling.TechnicalException;
import de.ozgcloud.eingang.common.formdata.IncomingFile;
import de.ozgcloud.eingang.common.formdata.IncomingFileGroup;
import de.ozgcloud.eingang.xta.EingangRepresentationsAndAttachments;
import de.ozgcloud.eingang.xta.XtaIncomingFilesMapper;
import de.ozgcloud.eingang.xta.zip.ZipFileExtractor;
import de.ozgcloud.xta.client.model.XtaMessage;
import lombok.RequiredArgsConstructor;
import lombok.extern.log4j.Log4j2;
......@@ -46,15 +49,64 @@ public class XdomeaMessageDataMapper {
static final String ATTACHMENT_GROUP_NAME = "Dokument";
private final XdomeaXMLValueReader valueReader;
private final XtaIncomingFilesMapper xtaIncomingFilesMapper;
private final ZipFileExtractor zipFileExtractor;
public EingangRepresentationsAndAttachments extractEingangRepresentationsAndAttachments(XtaMessage message) {
var incomingZipFile = xtaIncomingFilesMapper.toIncomingFile(message.messageFile());
try {
return tryExtractEingangRepresentationsAndAttachments(incomingZipFile);
} catch (RuntimeException e) {
LOG.error("Error while extracting Xdomea ZIP file!", e);
return EingangRepresentationsAndAttachments.builder()
.primaryFormDataFileName("")
.primaryFormDataPdfFileName("")
.representations(List.of(incomingZipFile))
.attachments(List.of())
.build();
}
}
EingangRepresentationsAndAttachments tryExtractEingangRepresentationsAndAttachments(IncomingFile zipFile) {
return mapEingangRepresentationsAndAttachments(
zipFileExtractor.extractIncomingFilesSafely(zipFile)
);
}
public EingangRepresentationsAndAttachments mapIncomingFilesToRepresentationsAttachmentsPair(List<IncomingFile> incomingFileList) {
EingangRepresentationsAndAttachments mapEingangRepresentationsAndAttachments(List<IncomingFile> incomingFileList) {
return removeUuidPrefixFromEingangFiles(
mapRawEingangRepresentationsAndAttachments(incomingFileList)
);
}
private EingangRepresentationsAndAttachments removeUuidPrefixFromEingangFiles(EingangRepresentationsAndAttachments eingang) {
return EingangRepresentationsAndAttachments.builder()
.primaryFormDataFileName(removeUuidPrefix(eingang.primaryFormDataFileName()))
.primaryFormDataPdfFileName(removeUuidPrefix(eingang.primaryFormDataPdfFileName()))
.representations(removeUuidPrefixFromIncomingFiles(eingang.representations()))
.attachments(removeUuidPrefixFromIncomingFileGroups(eingang.attachments()))
.build();
}
private EingangRepresentationsAndAttachments mapRawEingangRepresentationsAndAttachments(List<IncomingFile> incomingFileList) {
var xdomeaMessageData = mapIncomingFilesToXdomeaMessageData(incomingFileList);
return EingangRepresentationsAndAttachments.builder()
.representations(removeUuidPrefixFromIncomingFiles(getPairRepresentations(xdomeaMessageData)))
.attachments(removeUuidPrefixFromIncomingFileGroups(xdomeaMessageData.attachments()))
.primaryFormDataFileName(findRepresentationFileNameBySuffixFromMetadata(xdomeaMessageData, ".xml"))
.primaryFormDataPdfFileName(findRepresentationFileNameBySuffixFromMetadata(xdomeaMessageData, ".pdf"))
.representations(getPairRepresentations(xdomeaMessageData))
.attachments(xdomeaMessageData.attachments())
.build();
}
private String findRepresentationFileNameBySuffixFromMetadata(XdomeaMessageData xdomeaMessageData, String suffix) {
return findRepresentationFileNameBySuffix(
xdomeaMessageData.representations().stream()
.map(IncomingFile::getName)
.toList(),
suffix
);
}
private List<IncomingFileGroup> removeUuidPrefixFromIncomingFileGroups(List<IncomingFileGroup> incomingFileGroups) {
return incomingFileGroups.stream()
.map(group -> group.toBuilder()
......@@ -116,10 +168,7 @@ public class XdomeaMessageDataMapper {
}
private List<IncomingFile> getRepresentations(List<String> representationFileNames, Map<String, IncomingFile> fileNameToFileMap) {
return getFilesByName(
movePrimaryRepresentationFileNameToFirstPosition(representationFileNames),
fileNameToFileMap
);
return getFilesByName(representationFileNames.stream(), fileNameToFileMap);
}
private List<IncomingFileGroup> getAttachments(Stream<String> attachmentFileNames, Map<String, IncomingFile> fileNameToFileMap) {
......@@ -137,14 +186,6 @@ public class XdomeaMessageDataMapper {
.toList();
}
private Stream<String> movePrimaryRepresentationFileNameToFirstPosition(List<String> representationFileNames) {
var primaryRepresentationFileName = findPrimaryRepresentationName(representationFileNames);
return Stream.concat(
Stream.of(primaryRepresentationFileName),
dropNames(representationFileNames.stream(), Set.of(primaryRepresentationFileName))
);
}
private List<IncomingFile> getFilesByName(Stream<String> names, Map<String, IncomingFile> fileNameToFileMap) {
return names.map(fileNameToFileMap::get).toList();
}
......@@ -153,16 +194,17 @@ public class XdomeaMessageDataMapper {
return names.filter(name -> !namesToDrop.contains(name));
}
String findPrimaryRepresentationName(List<String> representationFileNames) {
var xmlFileNames = representationFileNames.stream()
.filter(name -> name.endsWith(".xml"))
String findRepresentationFileNameBySuffix(List<String> representationFileNames, String suffix) {
var fileNames = representationFileNames.stream()
.filter(name -> name.endsWith(suffix))
.toList();
if (xmlFileNames.isEmpty()) {
throw new TechnicalException("No xml representation file name found!");
} else if (xmlFileNames.size() > 1) {
LOG.warn("There is more than one xml representations. Choosing the first of {}.", xmlFileNames.size());
if (fileNames.isEmpty()) {
LOG.warn("There is no representation with suffix {}!.", suffix);
return "";
} else if (fileNames.size() > 1) {
LOG.warn("There is more than one representation with suffix {}. Choosing the first of {}.", suffix, fileNames.size());
}
return xmlFileNames.getFirst();
return fileNames.getFirst();
}
IncomingFile findXdomeaXMLFile(List<IncomingFile> incomingFileList) {
......
......@@ -24,44 +24,28 @@ package de.ozgcloud.eingang.xta;
import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.Objects;
import java.util.stream.Stream;
import de.ozgcloud.common.binaryfile.TempFileUtils;
import de.ozgcloud.eingang.common.errorhandling.TechnicalException;
import jakarta.activation.DataHandler;
import org.springframework.stereotype.Component;
import de.ozgcloud.common.binaryfile.TempFileUtils;
import de.ozgcloud.eingang.common.errorhandling.TechnicalException;
import de.ozgcloud.eingang.common.formdata.IncomingFile;
import de.ozgcloud.eingang.xta.zip.ZipFileExtractor;
import de.ozgcloud.xta.client.model.XtaFile;
import lombok.RequiredArgsConstructor;
import lombok.extern.log4j.Log4j2;
@Log4j2
@Component
@RequiredArgsConstructor
class XtaIncomingFilesMapper {
private final ZipFileExtractor zipFileExtractor;
public class XtaIncomingFilesMapper {
public List<IncomingFile> toIncomingFiles(XtaFile messageFile) {
if (Objects.nonNull(messageFile)) {
return Stream.of(messageFile)
.map(this::toIncomingFile)
.flatMap(this::tryToExtractZip)
.toList();
}
return List.of();
}
IncomingFile toIncomingFile(XtaFile messageFile) {
File tmpFile = persistToFile(messageFile.content());
public IncomingFile toIncomingFile(XtaFile file) {
File tmpFile = persistToFile(file.content());
return IncomingFile.builder()
.name(messageFile.name())
.contentType(messageFile.contentType())
.name(file.name())
.contentType(file.contentType())
.file(tmpFile)
.size(tmpFile.length())
.build();
......@@ -71,17 +55,7 @@ class XtaIncomingFilesMapper {
try (var inputStream = data.getInputStream()) {
return TempFileUtils.writeTmpFile(inputStream);
} catch (IOException e) {
throw new TechnicalException("Error writing Attachment to temp file", e);
}
}
Stream<IncomingFile> tryToExtractZip(IncomingFile incomingFile) {
try {
List<IncomingFile> extractedZips = zipFileExtractor.extractIncomingFilesSafely(incomingFile);
return extractedZips.stream();
} catch (RuntimeException e) {
return Stream.of(incomingFile);
throw new TechnicalException("Error writing xta file to temp file", e);
}
}
}
......@@ -28,15 +28,15 @@ import java.util.Optional;
import org.mapstruct.Context;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.Named;
import de.ozgcloud.eingang.common.formdata.FormData;
import de.ozgcloud.eingang.common.formdata.FormHeader;
import de.ozgcloud.eingang.common.formdata.FormMetaData;
import de.ozgcloud.eingang.common.vorgang.VorgangNummerSupplier;
import de.ozgcloud.eingang.semantik.enginebased.FilesMapperHelper;
import de.ozgcloud.xta.client.model.XtaMessageMetaData;
@Mapper(imports = { FilesMapperHelper.class, XtaMapperHelper.class })
@Mapper(imports = { FilesMapperHelper.class })
interface XtaMessageMapper {
int VORGANG_NUMMER_SUFFIX_LENGTH = 4;
......@@ -46,14 +46,26 @@ interface XtaMessageMapper {
@Mapping(target = "zustaendigeStelle", ignore = true)
@Mapping(target = "zustaendigeStelles", ignore = true)
@Mapping(target = "header", source = "metaData")
@Mapping(target = "numberOfAttachments", expression = "java(FilesMapperHelper.countAttachedFiles(representationsAttachmentsPair.attachments()))")
@Mapping(target = "numberOfRepresentations", dependsOn = "representations", expression = "java(representationsAttachmentsPair.representations().size())")
@Mapping(target = "numberOfAttachments", expression = "java(FilesMapperHelper.countAttachedFiles(eingang.attachments()))")
@Mapping(target = "numberOfRepresentations", dependsOn = "representations", expression = "java(eingang.representations().size())")
@Mapping(target = "representation", ignore = true)
@Mapping(target = "attachment", ignore = true)
@Mapping(target = "control.metaData", source = "metaData")
FormData toFormData(EingangRepresentationsAndAttachments representationsAttachmentsPair, XtaMessageMetaData metaData,
@Mapping(target = "control", expression = "java( toFormDataControl(eingang, metaData) )")
FormData toFormData(EingangRepresentationsAndAttachments eingang, XtaMessageMetaData metaData,
@Context VorgangNummerSupplier vorgangNummerSupplier);
default FormData.FormDataControl toFormDataControl(EingangRepresentationsAndAttachments eingang, XtaMessageMetaData metaData) {
return FormData.FormDataControl.builder()
.metaData(Optional.of(formMetaDataFromMetaData(metaData)))
.representations(Optional.of(toEingangRepresentations(eingang)))
.build();
}
@Mapping(target = "primaryFormDataRepresentation", source = "primaryFormDataFileName")
@Mapping(target = "primaryFormDataPdfRepresentation", source = "primaryFormDataPdfFileName")
@Named("toEingangRepresentations")
FormData.Representations toEingangRepresentations(EingangRepresentationsAndAttachments eingang);
@Mapping(target = "formId", source = "messageTypeCode")
@Mapping(target = "requestId", source = "messageId")
@Mapping(target = "vorgangNummer", expression = "java(vorgangNummerSupplier.get(VORGANG_NUMMER_SUFFIX_LENGTH))")
......@@ -79,8 +91,4 @@ interface XtaMessageMapper {
return XtaMessageId.from(id);
}
default Optional<FormMetaData> mapMetaData(XtaMessageMetaData value) {
return Optional.ofNullable(formMetaDataFromMetaData(value));
}
}
......@@ -23,34 +23,27 @@
*/
package de.ozgcloud.eingang.xta;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.function.Consumer;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import de.ozgcloud.eingang.common.errorhandling.TechnicalException;
import de.ozgcloud.eingang.common.formdata.FormData;
import de.ozgcloud.eingang.common.formdata.FormData.Representations;
import de.ozgcloud.eingang.common.formdata.IncomingFile;
import de.ozgcloud.eingang.common.formdata.IncomingFileGroup;
import de.ozgcloud.eingang.common.vorgang.VorgangNummerSupplier;
import de.ozgcloud.eingang.fim.FimMessageDataMapper;
import de.ozgcloud.eingang.semantik.SemantikAdapter;
import de.ozgcloud.eingang.xdomea.XdomeaMessageDataMapper;
import de.ozgcloud.xta.client.XtaClient;
import de.ozgcloud.xta.client.exception.XtaClientException;
import de.ozgcloud.xta.client.model.XtaFile;
import de.ozgcloud.xta.client.model.XtaMessage;
import de.ozgcloud.xta.client.model.XtaMessageMetaData;
import de.ozgcloud.xta.client.model.XtaMessageStatus;
import de.ozgcloud.xta.client.model.XtaTransportReport;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import lombok.extern.log4j.Log4j2;
@Service
@Log4j2
......@@ -69,8 +62,7 @@ class XtaService {
private final XtaMessageMapper mapper;
private final VorgangNummerSupplier vorgangNummerSupplier;
private final XdomeaMessageDataMapper xdomeaMessageDataMapper;
private final XtaIncomingFilesMapper xtaIncomingFilesMapper;
private final FimMessageDataMapper fimMessageDataMapper;
public void fetchMessages() throws XtaClientException {
......@@ -87,7 +79,7 @@ class XtaService {
try {
return Optional.of(getFormData(xtaMessage));
} catch (RuntimeException exception) {
LOG.error("Failed to process xta message (id: %s)".formatted(xtaMessage.metaData().messageId()), exception);
LOG.error("Failed to process xta message with id: {}", xtaMessage.metaData().messageId(), exception);
return Optional.empty();
}
}
......@@ -102,56 +94,25 @@ class XtaService {
}
FormData getFormData(XtaMessage xtaMessage) {
var metaData = xtaMessage.metaData();
var incomingFiles = xtaIncomingFilesMapper.toIncomingFiles(xtaMessage.messageFile());
var representationsAttachmentsPair = getRepresentationsAttachmentsPair(metaData, incomingFiles);
var formData = mapper.toFormData(representationsAttachmentsPair, metaData, vorgangNummerSupplier);
formData = addAttachments(xtaMessage, formData);
return addRepresentations(formData, xtaMessage.messageFile().name());
return mapper.toFormData(
getRepresentationsAndAttachments(xtaMessage),
xtaMessage.metaData(),
vorgangNummerSupplier
);
}
EingangRepresentationsAndAttachments getRepresentationsAttachmentsPair(XtaMessageMetaData metaData, List<IncomingFile> incomingFiles) {
EingangRepresentationsAndAttachments getRepresentationsAndAttachments(XtaMessage message) {
var metaData = message.metaData();
if (isXDomeaMessageType(metaData.messageTypeCode())) {
return xdomeaMessageDataMapper.mapIncomingFilesToRepresentationsAttachmentsPair(incomingFiles);
return xdomeaMessageDataMapper.extractEingangRepresentationsAndAttachments(message);
}
if (isFimMessageType(metaData.messageTypeCode())) {
return mapIncomingFilesToRepresentations(incomingFiles);
return fimMessageDataMapper.mapEingangRepresentationsAndAttachments(message);
}
throw new TechnicalException("Unexpected XTA message type: %s".formatted(metaData.messageTypeCode()));
}
FormData addAttachments(XtaMessage msg, FormData inFormData) {
var attachments = buildAttachmentsInFiles(msg.attachmentFiles());
if (CollectionUtils.isNotEmpty(attachments)) {
return inFormData.toBuilder()
.attachment(IncomingFileGroup.builder().name("sonstige").files(attachments).build())
.numberOfAttachments(attachments.size())
.build();
}
return inFormData;
}
private List<IncomingFile> buildAttachmentsInFiles(Collection<XtaFile> attachmentFiles) {
return attachmentFiles.stream().map(xtaIncomingFilesMapper::toIncomingFile).toList();
}
FormData addRepresentations(FormData formData, String primaryFormDataMessage) {
return formData.toBuilder().control(
formData.getControl().toBuilder()
.representations(Optional.of(buildRepresentations(formData.getControl().getRepresentations(), primaryFormDataMessage)))
.build())
.build();
}
private Representations buildRepresentations(Optional<Representations> base, String primaryFormDataMessage) {
return base.map(Representations::toBuilder).orElseGet(Representations::builder)
.primaryFormDataRepresentation(primaryFormDataMessage)
.build();
}
private boolean isXDomeaMessageType(String messageType) {
return StringUtils.equals(messageType, XDOMEA_0201_MESSAGE_TYPE);
}
......@@ -160,13 +121,6 @@ class XtaService {
return StringUtils.startsWith(messageType, FIM_MESSAGE_TYPE_PREFIX);
}
EingangRepresentationsAndAttachments mapIncomingFilesToRepresentations(List<IncomingFile> incomingFiles) {
return EingangRepresentationsAndAttachments.builder()
.representations(incomingFiles)
.attachments(Collections.emptyList())
.build();
}
void logTransportReports(List<XtaTransportReport> transportReports) {
for (var transportReport : transportReports) {
if (transportReport.status() == XtaMessageStatus.GREEN) {
......
package de.ozgcloud.eingang.fim;
import static de.ozgcloud.eingang.fim.FimMessageDataMapper.*;
import static org.assertj.core.api.Assertions.*;
import static org.mockito.Mockito.*;
import java.util.List;
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.InjectMocks;
import org.mockito.Mock;
import org.mockito.Spy;
import de.ozgcloud.eingang.common.formdata.IncomingFile;
import de.ozgcloud.eingang.common.formdata.IncomingFileGroup;
import de.ozgcloud.eingang.xta.EingangRepresentationsAndAttachments;
import de.ozgcloud.eingang.xta.XtaFileTestFactory;
import de.ozgcloud.eingang.xta.XtaIncomingFilesMapper;
import de.ozgcloud.eingang.xta.XtaMessageTestFactory;
import de.ozgcloud.xta.client.model.XtaFile;
import de.ozgcloud.xta.client.model.XtaMessage;
class FimMessageDataMapperTest {
@Spy
@InjectMocks
private FimMessageDataMapper mapper;
@Mock
private XtaIncomingFilesMapper xtaIncomingFilesMapper;
private final String primaryFormDataFileName = "test-fim.xml";
private final String fimAttachmentFileName = "upload.pdf";
private final String fimAttachment2FileName = "upload.png";
private final XtaFile primaryFormDataFile = XtaFileTestFactory.createBuilder()
.name(primaryFormDataFileName)
.build();
private final XtaFile fimAttachment1 = XtaFileTestFactory.createBuilder()
.name(fimAttachmentFileName)
.build();
private final XtaFile fimAttachment2 = XtaFileTestFactory.createBuilder()
.name(fimAttachment2FileName)
.build();
private final XtaMessage message = XtaMessageTestFactory.createBuilder()
.messageFile(primaryFormDataFile)
.attachmentFiles(List.of(fimAttachment1, fimAttachment2))
.build();
@DisplayName("map EingangRepresentationsAndAttachments")
@Nested
class TestMapEingangRepresentationsAndAttachments {
@Mock
private IncomingFile representationIncomingFile;
@Mock
private IncomingFileGroup attachmentIncomingFileGroup;
@BeforeEach
void mock() {
doReturn(List.of(representationIncomingFile)).when(mapper).getRepresentations(any());
doReturn(List.of(attachmentIncomingFileGroup)).when(mapper).getAttachmentGroups(any());
}
@DisplayName("should map primaryFormDataFileName")
@Test
void shouldMapPrimaryFormDataFileName() {
var result = mapEingangRepresentationsAndAttachments();
assertThat(result.primaryFormDataFileName()).isEqualTo(primaryFormDataFileName);
}
@DisplayName("should map primaryFormDataPdfFileName")
@Test
void shouldMapPrimaryFormDataPdfFileName() {
var result = mapEingangRepresentationsAndAttachments();
assertThat(result.primaryFormDataPdfFileName()).isEmpty();
}
@DisplayName("should call getRepresentations")
@Test
void shouldCallGetRepresentations() {
mapEingangRepresentationsAndAttachments();
verify(mapper).getRepresentations(message);
}
@DisplayName("should map representations")
@Test
void shouldMapRepresentations() {
var result = mapEingangRepresentationsAndAttachments();
assertThat(result.representations()).containsExactly(representationIncomingFile);
}
@DisplayName("should call getAttachmentGroups")
@Test
void shouldCallGetAttachmentGroups() {
mapEingangRepresentationsAndAttachments();
verify(mapper).getAttachmentGroups(message);
}
@DisplayName("should map attachments")
@Test
void shouldMapAttachments() {
var result = mapEingangRepresentationsAndAttachments();
assertThat(result.attachments()).containsExactly(attachmentIncomingFileGroup);
}
private EingangRepresentationsAndAttachments mapEingangRepresentationsAndAttachments() {
return mapper.mapEingangRepresentationsAndAttachments(message);
}
}
@DisplayName("get attachment groups")
@Nested
class TestGetAttachmentGroups {
@Mock
private IncomingFile attachmentIncomingFile1;
@Mock
private IncomingFile attachmentIncomingFile2;
@BeforeEach
void mock() {
when(xtaIncomingFilesMapper.toIncomingFile(any()))
.thenReturn(attachmentIncomingFile1)
.thenReturn(attachmentIncomingFile2);
}
@DisplayName("should call toIncomingFile")
@Test
void shouldCallToIncomingFile() {
mapper.getAttachmentGroups(message);
verify(xtaIncomingFilesMapper).toIncomingFile(fimAttachment1);
verify(xtaIncomingFilesMapper).toIncomingFile(fimAttachment2);
}
@DisplayName("should return group with name")
@Test
void shouldReturnGroupWithName() {
var result = mapper.getAttachmentGroups(message);
assertThat(result)
.extracting(IncomingFileGroup::getName)
.containsExactly(FIM_ATTACHMENT_GROUP_NAME);
}
@DisplayName("should return group with files")
@Test
void shouldReturnGroupWithFiles() {
var result = mapper.getAttachmentGroups(message);
assertThat(result)
.flatExtracting(IncomingFileGroup::getFiles)
.containsExactly(attachmentIncomingFile1, attachmentIncomingFile2);
}
}
@DisplayName("get representations")
@Nested
class TestGetRepresentations {
@Mock
private IncomingFile representationIncomingFile;
@BeforeEach
void mock() {
when(xtaIncomingFilesMapper.toIncomingFile(any())).thenReturn(representationIncomingFile);
}
@DisplayName("should call toIncomingFile")
@Test
void shouldCallToIncomingFile() {
mapper.getRepresentations(message);
verify(xtaIncomingFilesMapper).toIncomingFile(primaryFormDataFile);
}
@DisplayName("should return")
@Test
void shouldReturn() {
var result = mapper.getRepresentations(message);
assertThat(result).containsExactly(representationIncomingFile);
}
}
}
\ No newline at end of file
......@@ -26,7 +26,6 @@ package de.ozgcloud.eingang.xdomea;
import static de.ozgcloud.eingang.xdomea.XdomeaMessageDataMapper.*;
import static de.ozgcloud.eingang.xdomea.XdomeaMessageDataTestFactory.*;
import static org.assertj.core.api.Assertions.*;
import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.Mockito.*;
import java.util.Collection;
......@@ -47,19 +46,177 @@ import de.ozgcloud.eingang.common.errorhandling.TechnicalException;
import de.ozgcloud.eingang.common.formdata.IncomingFile;
import de.ozgcloud.eingang.common.formdata.IncomingFileGroup;
import de.ozgcloud.eingang.common.formdata.IncomingFileTestFactory;
import de.ozgcloud.eingang.xta.EingangRepresentationsAndAttachments;
import de.ozgcloud.eingang.xta.XtaIncomingFilesMapper;
import de.ozgcloud.eingang.xta.XtaMessageTestFactory;
import de.ozgcloud.eingang.xta.zip.ZipFileExtractor;
import de.ozgcloud.xta.client.model.XtaMessage;
class XdomeaMessageDataMapperTest {
@Spy
@InjectMocks
private XdomeaMessageDataMapper fileClassifier;
private XdomeaMessageDataMapper mapper;
@Mock
private XdomeaXMLValueReader valueReader;
@DisplayName("map incoming files to representations attachments pair")
@Mock
private ZipFileExtractor zipFileExtractor;
@Mock
private XtaIncomingFilesMapper xtaIncomingFilesMapper;
@DisplayName("extract EingangRepresentationsAndAttachments")
@Nested
class TestExtractEingangRepresentationsAndAttachments {
private final XtaMessage message = XtaMessageTestFactory.create();
@Mock
private IncomingFile zipFile;
@Mock
private EingangRepresentationsAndAttachments eingang;
@BeforeEach
void mock() {
when(xtaIncomingFilesMapper.toIncomingFile(any())).thenReturn(zipFile);
}
@DisplayName("without exception")
@Nested
class TestWithoutException {
@BeforeEach
void mock() {
doReturn(eingang).when(mapper).tryExtractEingangRepresentationsAndAttachments(any());
}
@DisplayName("should call toIncomingFile")
@Test
void shouldCallToIncomingFile() {
extractEingangRepresentationsAndAttachments();
verify(xtaIncomingFilesMapper).toIncomingFile(message.messageFile());
}
@DisplayName("should call tryExtractEingangRepresentationsAndAttachments")
@Test
void shouldCallTryExtractEingangRepresentationsAndAttachments() {
extractEingangRepresentationsAndAttachments();
verify(mapper).tryExtractEingangRepresentationsAndAttachments(zipFile);
}
@DisplayName("should return")
@Test
void shouldReturn() {
var result = extractEingangRepresentationsAndAttachments();
assertThat(result).isEqualTo(eingang);
}
}
@DisplayName("with exception")
@Nested
class TestWithException {
@Mock
private RuntimeException exception;
@BeforeEach
void mock() {
doThrow(exception).when(mapper).tryExtractEingangRepresentationsAndAttachments(any());
}
@DisplayName("should map primaryFormDataFileName to empty")
@Test
void shouldMapPrimaryFormDataFileNameToEmpty() {
var result = extractEingangRepresentationsAndAttachments();
assertThat(result.primaryFormDataFileName()).isEmpty();
}
@DisplayName("should map primaryFormDataPdfFileName to empty")
@Test
void shouldMapPrimaryFormDataPdfFileNameToEmpty() {
var result = extractEingangRepresentationsAndAttachments();
assertThat(result.primaryFormDataPdfFileName()).isEmpty();
}
@DisplayName("should map representations")
@Test
void shouldMapRepresentations() {
var result = extractEingangRepresentationsAndAttachments();
assertThat(result.representations()).containsExactly(zipFile);
}
@DisplayName("should map attachments to empty")
@Test
void shouldMapAttachmentsToEmpty() {
var result = extractEingangRepresentationsAndAttachments();
assertThat(result.attachments()).isEmpty();
}
}
private EingangRepresentationsAndAttachments extractEingangRepresentationsAndAttachments() {
return mapper.extractEingangRepresentationsAndAttachments(message);
}
}
@DisplayName("try extract EingangRepresentationsAndAttachments")
@Nested
class TestTryExtractEingangRepresentationsAndAttachments {
@Mock
private IncomingFile zipFile;
@Mock
private IncomingFile xdomeaXmlFile;
@Mock
private EingangRepresentationsAndAttachments eingang;
@BeforeEach
void mock() {
when(zipFileExtractor.extractIncomingFilesSafely(any())).thenReturn(List.of(xdomeaXmlFile));
doReturn(eingang).when(mapper).mapEingangRepresentationsAndAttachments(any());
}
@DisplayName("should call extractIncomingFilesSafely")
@Test
void shouldCallExtractIncomingFilesSafely() {
tryExtractEingangRepresentationsAndAttachments();
verify(zipFileExtractor).extractIncomingFilesSafely(zipFile);
}
@DisplayName("should call mapEingangRepresentationsAndAttachments")
@Test
void shouldCallMapEingangRepresentationsAndAttachments() {
tryExtractEingangRepresentationsAndAttachments();
verify(mapper).mapEingangRepresentationsAndAttachments(List.of(xdomeaXmlFile));
}
@DisplayName("should return")
@Test
void shouldReturn() {
var result = tryExtractEingangRepresentationsAndAttachments();
assertThat(result).isEqualTo(eingang);
}
private EingangRepresentationsAndAttachments tryExtractEingangRepresentationsAndAttachments() {
return mapper.tryExtractEingangRepresentationsAndAttachments(zipFile);
}
}
@DisplayName("map EingangRepresentationsAndAttachments")
@Nested
class TestMapIncomingFilesToEingangRepresentationsAndAttachments {
class TestMapEingangRepresentationsAndAttachments {
@Mock
private List<IncomingFile> incomingFileList;
......@@ -70,7 +227,7 @@ class XdomeaMessageDataMapperTest {
void shouldMapRepresentations(boolean useUuidPrefix) {
mockXdomeaMessageData(useUuidPrefix);
var pair = fileClassifier.mapIncomingFilesToRepresentationsAttachmentsPair(incomingFileList);
var pair = mapper.mapEingangRepresentationsAndAttachments(incomingFileList);
var representationFilenames = pair.representations().stream().map(IncomingFile::getName).toList();
assertThat(representationFilenames).containsExactly(XDOMEA_XML_NAME, REPR_XML_NAME, REPR_PDF_NAME);
......@@ -82,7 +239,7 @@ class XdomeaMessageDataMapperTest {
void shouldMapAttachments(boolean useUuidPrefix) {
mockXdomeaMessageData(useUuidPrefix);
var pair = fileClassifier.mapIncomingFilesToRepresentationsAttachmentsPair(incomingFileList);
var pair = mapper.mapEingangRepresentationsAndAttachments(incomingFileList);
var attachmentFilenames = pair.attachments().stream()
.map(IncomingFileGroup::getFiles)
......@@ -92,8 +249,30 @@ class XdomeaMessageDataMapperTest {
assertThat(attachmentFilenames).containsExactly(ATTATCHMENT_XML_NAME, ATTATCHMENT_PNG_NAME, ATTATCHMENT_PDF_NAME);
}
@DisplayName("should map primaryFormDataFileName")
@ParameterizedTest
@ValueSource(booleans = { true, false })
void shouldMapPrimaryFormDataFileName(boolean useUuidPrefix) {
mockXdomeaMessageData(useUuidPrefix);
var pair = mapper.mapEingangRepresentationsAndAttachments(incomingFileList);
assertThat(pair.primaryFormDataFileName()).isEqualTo(REPR_XML_NAME);
}
@DisplayName("should map primaryFormDataPdfFileName")
@ParameterizedTest
@ValueSource(booleans = { true, false })
void shouldMapPrimaryFormPdfDataFileName(boolean useUuidPrefix) {
mockXdomeaMessageData(useUuidPrefix);
var pair = mapper.mapEingangRepresentationsAndAttachments(incomingFileList);
assertThat(pair.primaryFormDataPdfFileName()).isEqualTo(REPR_PDF_NAME);
}
private void mockXdomeaMessageData(boolean useUuidPrefix) {
doReturn(XdomeaMessageDataTestFactory.create(useUuidPrefix)).when(fileClassifier).mapIncomingFilesToXdomeaMessageData(incomingFileList);
doReturn(XdomeaMessageDataTestFactory.create(useUuidPrefix)).when(mapper).mapIncomingFilesToXdomeaMessageData(incomingFileList);
}
}
......@@ -110,7 +289,7 @@ class XdomeaMessageDataMapperTest {
void shouldThrowIfNotFound() {
var incomingFilesWithout = List.of(IncomingFileTestFactory.createBuilder().name(FILE_NAME_WITHOUT_SUFFIX).build());
assertThatThrownBy(() -> fileClassifier.findXdomeaXMLFile(incomingFilesWithout))
assertThatThrownBy(() -> mapper.findXdomeaXMLFile(incomingFilesWithout))
.isInstanceOf(TechnicalException.class);
}
......@@ -123,37 +302,59 @@ class XdomeaMessageDataMapperTest {
targetIncomingFile
);
var primaryRepresentation = fileClassifier.findXdomeaXMLFile(incomingFilesWith);
var primaryRepresentation = mapper.findXdomeaXMLFile(incomingFilesWith);
assertThat(primaryRepresentation).isEqualTo(targetIncomingFile);
}
}
@DisplayName("find primary representation name")
@DisplayName("find representation file name by suffix")
@Nested
class TestFindPrimaryRepresentationName {
private static final String FILE_NAME_WITHOUT_XML_SUFFIX = "some-file-name.pdf";
private static final String FILE_NAME_WITHOUT_XML_SUFFIX2 = "some-file-name.xml.pdf";
private static final String FILE_NAME_WITH_XML_SUFFIX = "some-file-name.xml";
private static final String FILE_NAME_WITH_XML_SUFFIX2 = "some-file-name.pdf.xml";
class TestFindRepresentationFileNameBySuffix {
private static final String PDF_FILE_NAME = "some-file-name.pdf";
private static final String PDF_FILE_NAME2 = "some-file-name.xml.pdf";
private static final String XML_FILE_NAME = "some-file-name.xml";
private static final String XML_FILE_NAME2 = "some-file-name.pdf.xml";
@DisplayName("should throw if no xml suffix")
@DisplayName("should return empty if no xml suffix")
@Test
void shouldThrowIfNoXmlSuffix() {
var listWithoutSuffix = List.of(FILE_NAME_WITHOUT_XML_SUFFIX, FILE_NAME_WITHOUT_XML_SUFFIX2);
void shouldReturnEmptyIfNoXmlSuffix() {
var namesWithSuffix = List.of(PDF_FILE_NAME, PDF_FILE_NAME2);
assertThrows(TechnicalException.class, () -> fileClassifier.findPrimaryRepresentationName(listWithoutSuffix));
var fileName = mapper.findRepresentationFileNameBySuffix(namesWithSuffix, ".xml");
assertThat(fileName).isEmpty();
}
@DisplayName("should return first with xml suffix")
@Test
void shouldReturnFirstWithXmlSuffix() {
var listWithSuffix = List.of(FILE_NAME_WITHOUT_XML_SUFFIX, FILE_NAME_WITH_XML_SUFFIX, FILE_NAME_WITHOUT_XML_SUFFIX2,
FILE_NAME_WITH_XML_SUFFIX2);
var namesWithSuffix = List.of(PDF_FILE_NAME, XML_FILE_NAME, PDF_FILE_NAME2,
XML_FILE_NAME2);
var fileName = fileClassifier.findPrimaryRepresentationName(listWithSuffix);
var fileName = mapper.findRepresentationFileNameBySuffix(namesWithSuffix, ".xml");
assertThat(fileName).isEqualTo(FILE_NAME_WITH_XML_SUFFIX);
assertThat(fileName).isEqualTo(XML_FILE_NAME);
}
@DisplayName("should return empty if no pdf suffix")
@Test
void shouldReturnEmptyIfNoPdfSuffix() {
var namesWithoutSuffix = List.of(XML_FILE_NAME, XML_FILE_NAME2);
var fileName = mapper.findRepresentationFileNameBySuffix(namesWithoutSuffix, ".pdf");
assertThat(fileName).isEmpty();
}
@DisplayName("should return first with pdf suffix")
@Test
void shouldReturnFirstWithPdfSuffix() {
var namesWithSuffix = List.of(PDF_FILE_NAME, XML_FILE_NAME, PDF_FILE_NAME2, XML_FILE_NAME2);
var fileName = mapper.findRepresentationFileNameBySuffix(namesWithSuffix, ".pdf");
assertThat(fileName).isEqualTo(PDF_FILE_NAME);
}
}
......@@ -178,13 +379,12 @@ class XdomeaMessageDataMapperTest {
)
.map(name -> IncomingFileTestFactory.createBuilder().name(name).build())
.toList();
doReturn(xdomeaXMLFile).when(fileClassifier).findXdomeaXMLFile(incomingFileList);
doReturn(xdomeaXMLFile).when(mapper).findXdomeaXMLFile(incomingFileList);
when(xdomeaXMLFile.getName()).thenReturn(XDOMEA_XML_NAME);
var representationFileNames = List.of(REPR_PDF_NAME, REPR_XML_NAME);
when(valueReader.readRepresentationFileNames(xdomeaXMLFile)).thenReturn(representationFileNames);
doReturn(REPR_XML_NAME).when(fileClassifier).findPrimaryRepresentationName(representationFileNames);
}
@DisplayName("should contain xdomea metadata file")
......@@ -204,8 +404,8 @@ class XdomeaMessageDataMapperTest {
var resultRepresentationFileNames = classification.representations().stream()
.map(IncomingFile::getName)
.toList();
// Expect that the primary representation xml file is moved to the first position
assertThat(resultRepresentationFileNames).isEqualTo(List.of(REPR_XML_NAME, REPR_PDF_NAME));
assertThat(resultRepresentationFileNames).isEqualTo(List.of(REPR_PDF_NAME, REPR_XML_NAME));
}
@DisplayName("should contain attachments")
......@@ -233,7 +433,7 @@ class XdomeaMessageDataMapperTest {
}
private XdomeaMessageData doClassify() {
return fileClassifier.mapIncomingFilesToXdomeaMessageData(incomingFileList);
return mapper.mapIncomingFilesToXdomeaMessageData(incomingFileList);
}
}
......
......@@ -31,22 +31,23 @@ import java.nio.charset.StandardCharsets;
import jakarta.activation.DataHandler;
import jakarta.activation.DataSource;
import jakarta.activation.FileDataSource;
import lombok.SneakyThrows;
import org.apache.commons.io.FileUtils;
import de.ozgcloud.xta.client.model.XtaFile;
import lombok.SneakyThrows;
class XtaFileTestFactory {
public class XtaFileTestFactory {
static final String NAME = "Test_File";
static final String CONTENT = "slkafj3jifsdasx";
static final String ZIP_CONTENT_TYPE = "application/zip";
public static final String NAME = "Test_File";
public static final String CONTENT = "slkafj3jifsdasx";
public static final String ZIP_CONTENT_TYPE = "application/zip";
static XtaFile create() {
public static XtaFile create() {
return createBuilder().build();
}
static XtaFile.XtaFileBuilder createBuilder() {
public static XtaFile.XtaFileBuilder createBuilder() {
return XtaFile.builder()
.name(NAME)
.contentType(ZIP_CONTENT_TYPE)
......
......@@ -23,53 +23,17 @@
package de.ozgcloud.eingang.xta;
import static org.assertj.core.api.Assertions.*;
import static org.mockito.Mockito.*;
import java.util.List;
import java.util.stream.Stream;
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.eingang.common.formdata.IncomingFile;
import de.ozgcloud.eingang.common.formdata.IncomingFileTestFactory;
import de.ozgcloud.eingang.xta.zip.ZipFileExtractor;
class XtaIncomingFilesMapperTest {
@Spy
@InjectMocks
private XtaIncomingFilesMapper mapper;
@Mock
private ZipFileExtractor extractor;
@Nested
class TestToIncomingFiles {
@Test
void shouldMapToIncomingFiles() {
var xtaFile = XtaFileTestFactory.create();
var incomingFile = IncomingFileTestFactory.create();
when(mapper.toIncomingFile(xtaFile)).thenReturn(incomingFile);
when(mapper.tryToExtractZip(incomingFile)).thenAnswer(x -> Stream.of(incomingFile));
mapper.toIncomingFiles(xtaFile);
inOrder(mapper).verify(mapper, calls(1)).toIncomingFile(xtaFile);
inOrder(mapper).verify(mapper, calls(1)).tryToExtractZip(incomingFile);
}
@Test
void shouldHandleMissingMessageFile() {
var fileGroup = mapper.toIncomingFiles(null);
assertThat(fileGroup).isEmpty();
}
}
@Nested
class ToIncomingFile {
@Test
......@@ -101,38 +65,4 @@ class XtaIncomingFilesMapperTest {
}
}
@Nested
class TestTryToExtractZip {
@Mock
IncomingFile outFile1;
@Mock
IncomingFile outFile2;
private final IncomingFile zipFile = IncomingFileTestFactory.createBuilder()
.name("attachments.zip")
.build();
@Test
void shouldExtractZipFiles() {
var expectedExtractedFiles = List.of(outFile1, outFile2);
when(extractor.extractIncomingFilesSafely(zipFile)).thenReturn(expectedExtractedFiles);
var extractedFiles = mapper.tryToExtractZip(zipFile).toList();
assertThat(extractedFiles).isEqualTo(expectedExtractedFiles);
}
@Test
void shouldIgnoreNonZipFiles() {
when(extractor.extractIncomingFilesSafely(zipFile)).thenThrow(new RuntimeException());
var incomingFile = IncomingFileTestFactory.create();
var extractedFiles = mapper.tryToExtractZip(incomingFile).toList();
assertThat(extractedFiles).containsExactly(incomingFile);
}
}
}
......@@ -28,6 +28,7 @@ import static org.assertj.core.api.Assertions.*;
import static org.mockito.Mockito.*;
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.mapstruct.factory.Mappers;
......@@ -36,6 +37,7 @@ import org.mockito.Mock;
import org.mockito.Spy;
import de.ozgcloud.eingang.common.formdata.FormData;
import de.ozgcloud.eingang.common.formdata.FormMetaData;
import de.ozgcloud.eingang.common.formdata.FormMetaDataTestFactory;
import de.ozgcloud.eingang.common.vorgang.VorgangNummerSupplier;
import de.ozgcloud.xta.client.model.XtaMessageMetaData;
......@@ -105,69 +107,93 @@ class XtaMessageMapperTest {
}
@Test
void shouldSetFormEngineName() {
void shouldSetDesinationId() {
var formData = doMapping();
assertThat(formData.getHeader().getFormEngineName()).isEqualTo(FormHeaderTestFactory.XDOMEA_FORM_ENGINE_NAME);
assertThat(formData.getControl().getMetaData()).isPresent().get()
.extracting(metaData -> metaData.getEntry(XtaFormMetaData.XTA_IDENTIFIER_ENTRY_NAME))
.isEqualTo(FormMetaDataTestFactory.XTA_IDENTIFIER);
}
@DisplayName("should map XtaFormMetaData service")
@Test
void shouldSetDesinationId() {
void shouldMapXtaFormMetaDataService() {
var formData = doMapping();
assertThat(formData.getControl().getMetaData()).isPresent().get()
.extracting(metaData -> metaData.getEntry(XtaFormMetaData.XTA_IDENTIFIER_ENTRY_NAME))
.isEqualTo(FormMetaDataTestFactory.XTA_IDENTIFIER);
.extracting(metaData -> metaData.getEntry(XtaFormMetaData.SERVICE_ENTRY_NAME))
.isEqualTo(xtaMessageMetaData.service());
}
private FormData doMapping() {
return mapper.toFormData(eingangRepresentationsAndAttachments, xtaMessageMetaData, vorgangNummerSupplier);
@DisplayName("should map XtaFormMetaData origin")
@Test
void shouldMapXtaFormMetaDataOrigin() {
var formData = doMapping();
assertThat(formData.getControl().getMetaData()).isPresent().get()
.extracting(FormMetaData::getOrigin)
.isEqualTo(xtaMessageMetaData.deliveryAttributesOrigin());
}
}
@Nested
class TestFormMetaDataFromMetaData {
private XtaMessageMetaData metaData;
@DisplayName("should map XtaFormMetaData delivery")
@Test
void shouldMapXtaFormMetaDataDelivery() {
var formData = doMapping();
@BeforeEach
void before() {
metaData = XtaMessageMetaDataTestFactory.create();
assertThat(formData.getControl().getMetaData()).isPresent().get()
.extracting(FormMetaData::getDelivery)
.isEqualTo(xtaMessageMetaData.deliveryAttributesDelivery());
}
@DisplayName("should map XtaFormMetaData messageId")
@Test
void shouldSetOrigin() {
var formMetaData = mapper.formMetaDataFromMetaData(metaData);
void shouldMapXtaFormMetaDataMessageId() {
var formData = doMapping();
assertThat(formMetaData.getOrigin()).isEqualTo(metaData.deliveryAttributesOrigin());
assertThat(formData.getControl().getMetaData()).isPresent().get()
.extracting(metaData -> metaData.getEntry(XtaFormMetaData.MESSAGE_ID_ENTRY_NAME))
.isEqualTo(xtaMessageMetaData.messageId());
}
@DisplayName("should map XtaFormMetaData messageType")
@Test
void shouldSetDelivery() {
var formMetaData = mapper.formMetaDataFromMetaData(metaData);
void shouldMapXtaFormMetaDataMessageType() {
var formData = doMapping();
assertThat(formMetaData.getDelivery()).isEqualTo(metaData.deliveryAttributesDelivery());
assertThat(formData.getControl().getMetaData()).isPresent().get()
.extracting(metaData -> metaData.getEntry(XtaFormMetaData.MESSAGE_TYPE_ENTRY_NAME))
.isEqualTo(xtaMessageMetaData.messageTypeCode());
}
}
@Nested
class TestToFimFormData {
@DisplayName("should map XtaFormMetaData xtaIdentifier")
@Test
void shouldMapXtaFormMetaDataXtaIdentifier() {
var formData = doMapping();
private XtaMessageMetaData xtaMessageMetaData;
private EingangRepresentationsAndAttachments eingangRepresentationsAndAttachments;
assertThat(formData.getControl().getMetaData()).isPresent().get()
.extracting(metaData -> metaData.getEntry(XtaFormMetaData.XTA_IDENTIFIER_ENTRY_NAME))
.isEqualTo(xtaMessageMetaData.readerIdentifier().value());
}
@BeforeEach
void mock() {
xtaMessageMetaData = XtaMessageMetaDataTestFactory.createFim();
eingangRepresentationsAndAttachments = EingangRepresentationsAndAttachmentsTestFactory.create();
when(vorgangNummerSupplier.get(VORGANG_NUMMER_SUFFIX_LENGTH)).thenReturn(FormHeaderTestFactory.VORGANGNUMMER);
@DisplayName("should map formEngineName")
@Test
void shouldMapFormEngineName() {
var formData = doMapping();
assertThat(formData.getHeader().getFormEngineName()).isEqualTo(FormHeaderTestFactory.XDOMEA_FORM_ENGINE_NAME);
}
@DisplayName("should map formEngineName for fim")
@Test
void shouldSetFormEngineName() {
var formData = mapper.toFormData(eingangRepresentationsAndAttachments, xtaMessageMetaData, vorgangNummerSupplier);
void shouldMapFormEngineNameForFim() {
var formData = mapper.toFormData(eingangRepresentationsAndAttachments, XtaMessageMetaDataTestFactory.createFim(), vorgangNummerSupplier);
assertThat(formData.getHeader().getFormEngineName()).isEqualTo(FormHeaderTestFactory.FIM_FORM_ENGINE_NAME);
}
private FormData doMapping() {
return mapper.toFormData(eingangRepresentationsAndAttachments, xtaMessageMetaData, vorgangNummerSupplier);
}
}
}
......@@ -28,18 +28,18 @@ import java.util.List;
import de.ozgcloud.xta.client.model.XtaFile;
import de.ozgcloud.xta.client.model.XtaMessage;
class XtaMessageTestFactory {
public class XtaMessageTestFactory {
static final XtaMessageId MESSAGE_ID = XtaMessageId.from("urn:de:xta:messageid:dataport_xta_210:81e40808-91c6-4765-aaf4-1aa62fec8be9");
static final XtaFile attachment = XtaFileTestFactory.create();
static final String PRIMARY_FORM_DATA_MESSAGE = XtaFileTestFactory.NAME;
static XtaMessage create() {
public static XtaMessage create() {
return createBuilder().build();
}
static XtaMessage.XtaMessageBuilder createBuilder() {
public static XtaMessage.XtaMessageBuilder createBuilder() {
return XtaMessage.builder()
.metaData(XtaMessageMetaDataTestFactory.create())
.messageFile(XtaFileTestFactory.create())
......
......@@ -28,34 +28,28 @@ import static org.assertj.core.api.Assertions.*;
import static org.mockito.ArgumentMatchers.*;
import static org.mockito.Mockito.*;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import lombok.SneakyThrows;
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 de.ozgcloud.eingang.common.errorhandling.TechnicalException;
import de.ozgcloud.eingang.common.formdata.FormData;
import de.ozgcloud.eingang.common.formdata.FormData.Representations;
import de.ozgcloud.eingang.common.formdata.FormDataControlTestFactory;
import de.ozgcloud.eingang.common.formdata.IncomingFile;
import de.ozgcloud.eingang.common.formdata.IncomingFileTestFactory;
import de.ozgcloud.eingang.common.vorgang.VorgangNummerSupplier;
import de.ozgcloud.eingang.fim.FimMessageDataMapper;
import de.ozgcloud.eingang.semantik.SemantikAdapter;
import de.ozgcloud.eingang.xdomea.XdomeaMessageDataMapper;
import de.ozgcloud.xta.client.XtaClient;
import de.ozgcloud.xta.client.model.XtaMessage;
import de.ozgcloud.xta.client.model.XtaMessageMetaData;
import de.ozgcloud.xta.client.model.XtaTransportReport;
import lombok.SneakyThrows;
class XtaServiceTest {
......@@ -73,10 +67,10 @@ class XtaServiceTest {
private SemantikAdapter semantikAdapter;
@Mock
private XtaIncomingFilesMapper incomingFilesMapper;
private XdomeaMessageDataMapper xdomeaMessageDataMapper;
@Mock
private XdomeaMessageDataMapper xdomeaMessageDataMapper;
private FimMessageDataMapper fimMessageDataMapper;
@Mock
private FormData formData;
......@@ -199,187 +193,123 @@ class XtaServiceTest {
private final XtaMessage message = XtaMessageTestFactory.create();
private final XtaMessageMetaData messageMetaData = XtaMessageMetaDataTestFactory.create();
private final FormData mappedFormData = FormDataTestFactory.create();
private EingangRepresentationsAndAttachments classification;
@Captor
private ArgumentCaptor<XtaMessageMetaData> messageMetaDataCaptor;
@Captor
private ArgumentCaptor<EingangRepresentationsAndAttachments> classificationCaptor;
private final EingangRepresentationsAndAttachments eingang = EingangRepresentationsAndAttachmentsTestFactory.create();
@BeforeEach
void init() {
classification = EingangRepresentationsAndAttachmentsTestFactory.create();
var incomingFiles = List.of(IncomingFileTestFactory.create(), IncomingFileTestFactory.create());
when(incomingFilesMapper.toIncomingFiles(message.messageFile())).thenReturn(incomingFiles);
doReturn(classification).when(service).getRepresentationsAttachmentsPair(messageMetaData, incomingFiles);
}
@BeforeEach
void mockMessageMapping() {
void mock() {
doReturn(eingang).when(service).getRepresentationsAndAttachments(any());
when(mapper.toFormData(any(), any(), any())).thenReturn(mappedFormData);
}
@DisplayName("should call getRepresentationsAndAttachments")
@Test
void shouldCallMapper() {
void shouldCallGetRepresentationsAndAttachments() {
service.getFormData(message);
verify(mapper).toFormData(classification, messageMetaData, vorgangNummerSupplier);
verify(service).getRepresentationsAndAttachments(message);
}
@DisplayName("should call toFormData")
@Test
void shouldCallMapperToFormData() {
void shouldCallToFormData() {
service.getFormData(message);
verify(mapper).toFormData(classificationCaptor.capture(), messageMetaDataCaptor.capture(), eq(vorgangNummerSupplier));
assertThat(messageMetaDataCaptor.getValue()).isEqualTo(messageMetaData);
assertThat(classificationCaptor.getValue()).isEqualTo(classification);
verify(mapper).toFormData(eingang, messageMetaData, vorgangNummerSupplier);
}
@DisplayName("should return")
@Test
void shouldCallAddAttachments() {
service.getFormData(message);
verify(service).addAttachments(message, mappedFormData);
}
@Test
void shouldReturnMappedResult() {
doReturn(mappedFormData).when(service).addRepresentations(any(), any());
void shouldReturn() {
var result = service.getFormData(message);
assertThat(result).isEqualTo(mappedFormData);
}
}
@DisplayName("add attachments")
@DisplayName("get representations and attachments")
@Nested
class TestAddAttachments {
private final FormData inFormData = FormDataTestFactory.createBuilder().clearAttachments().numberOfAttachments(0).build();
class TestGetRepresentationsAndAttachments {
@Test
void shouldAddAttachments() {
var result = service.addAttachments(XtaMessageTestFactory.create(), inFormData);
@Mock
private EingangRepresentationsAndAttachments eingang;
assertThat(result.getAttachments()).hasSize(1);
assertThat(result.getNumberOfAttachments()).isEqualTo(1);
}
@DisplayName("with xdomea type")
@Nested
class TestWithXdomeaType {
@Test
void shouldWorkWithoutAnyAttachment() {
var result = service.addAttachments(XtaMessageTestFactory.createBuilder().attachmentFiles(Collections.emptyList()).build(), inFormData);
private final XtaMessage xdomeaMessage = XtaMessageTestFactory.createBuilder()
.metaData(XtaMessageMetaDataTestFactory.createBuilder()
.messageTypeCode(XtaService.XDOMEA_0201_MESSAGE_TYPE)
.build())
.build();
assertThat(result.getAttachments()).isEmpty();
assertThat(result.getNumberOfAttachments()).isZero();
}
}
@BeforeEach
void mock() {
when(xdomeaMessageDataMapper.extractEingangRepresentationsAndAttachments(any())).thenReturn(eingang);
}
@DisplayName("get representations attachments pair")
@Nested
class TestGetEingangRepresentationsAndAttachments {
@Mock
private XtaMessageMetaData messageMetaData;
@DisplayName("should call extractEingangRepresentationsAndAttachments")
@Test
void shouldCallExtractEingangRepresentationsAndAttachments() {
service.getRepresentationsAndAttachments(xdomeaMessage);
@Mock
private EingangRepresentationsAndAttachments classification;
verify(xdomeaMessageDataMapper).extractEingangRepresentationsAndAttachments(xdomeaMessage);
}
private List<IncomingFile> incomingFiles;
@DisplayName("should return")
@Test
void shouldReturn() {
var result = service.getRepresentationsAndAttachments(xdomeaMessage);
@BeforeEach
void mock() {
incomingFiles = List.of(IncomingFileTestFactory.create(), IncomingFileTestFactory.create());
assertThat(result).isEqualTo(eingang);
}
}
@DisplayName("should use correct mapper xdomea message type")
@Test
void shouldUseCorrectMapperXdomeaMessageType() {
when(messageMetaData.messageTypeCode()).thenReturn(XtaService.XDOMEA_0201_MESSAGE_TYPE);
when(xdomeaMessageDataMapper.mapIncomingFilesToRepresentationsAttachmentsPair(incomingFiles))
.thenReturn(classification);
var result = service.getRepresentationsAttachmentsPair(messageMetaData, incomingFiles);
@DisplayName("with fim type")
@Nested
class TestWithFimType {
private final XtaMessage fimMessage = XtaMessageTestFactory.createBuilder()
.metaData(XtaMessageMetaDataTestFactory.createBuilder()
.messageTypeCode(FIM_MESSAGE_TYPE_PREFIX + "836487")
.build())
.build();
@BeforeEach
void mock() {
when(fimMessageDataMapper.mapEingangRepresentationsAndAttachments(any())).thenReturn(eingang);
}
assertThat(result).isEqualTo(classification);
}
@DisplayName("should call mapIncomingFilesToRepresentations")
@Test
void shouldCallMapIncomingFilesToRepresentations() {
service.getRepresentationsAndAttachments(fimMessage);
@DisplayName("should use correct mapping for FIM message")
@Test
void shouldUseCorrectMappingForFimMessage() {
when(messageMetaData.messageTypeCode()).thenReturn(FIM_MESSAGE_TYPE_PREFIX + "836487");
doReturn(classification).when(service).mapIncomingFilesToRepresentations(incomingFiles);
verify(fimMessageDataMapper).mapEingangRepresentationsAndAttachments(fimMessage);
}
var result = service.getRepresentationsAttachmentsPair(messageMetaData, incomingFiles);
@DisplayName("should return")
@Test
void shouldReturn() {
var result = service.getRepresentationsAndAttachments(fimMessage);
assertThat(result).isEqualTo(classification);
assertThat(result).isEqualTo(eingang);
}
}
@DisplayName("should throw exception for unexpected message type")
@Test
void shouldThrowExceptionForUnexpectedMessageType() {
when(messageMetaData.messageTypeCode()).thenReturn("unexpected");
var unexpectedMessage = XtaMessageTestFactory.createBuilder()
.metaData(XtaMessageMetaDataTestFactory.createBuilder()
.messageTypeCode("unexpected")
.build())
.build();
assertThatThrownBy(() -> service.getRepresentationsAttachmentsPair(messageMetaData, incomingFiles))
assertThatThrownBy(() -> service.getRepresentationsAndAttachments(unexpectedMessage))
.isInstanceOf(TechnicalException.class);
}
}
@DisplayName("map incoming files to representations")
@Nested
class TestMapIncomingFilesToRepresentations {
private List<IncomingFile> incomingFiles;
@BeforeEach
void mock() {
incomingFiles = List.of(IncomingFileTestFactory.create(), IncomingFileTestFactory.create());
}
@DisplayName("should return representations with incoming files")
@Test
void shouldReturnRepresentationsWithIncomingFiles() {
var result = service.mapIncomingFilesToRepresentations(incomingFiles);
assertThat(result.representations()).isEqualTo(incomingFiles);
}
@DisplayName("should return attachments with empty list")
@Test
void shouldReturnAttachmentsWithEmptyList() {
var result = service.mapIncomingFilesToRepresentations(incomingFiles);
assertThat(result.attachments()).isEmpty();
}
}
@DisplayName("add representations")
@Nested
class TestAddRepresentations {
@Test
void shouldAddPrimaryRepresentation() {
var result = service.addRepresentations(FormDataTestFactory.create(), XtaMessageTestFactory.PRIMARY_FORM_DATA_MESSAGE);
assertThat(result.getControl().getRepresentations()).isPresent().get()
.extracting(Representations::getPrimaryFormDataRepresentation).isEqualTo(XtaMessageTestFactory.PRIMARY_FORM_DATA_MESSAGE);
}
@Test
void shouldRespectExistingRepresentation() {
var formDataWithRepresentation = FormDataTestFactory.createBuilder().control(FormDataControlTestFactory.createBuilder()
.representations(Optional.of(
Representations.builder().primaryFormDataPdfRepresentation("PDF_FILE").build()))
.build()).build();
var result = service.addRepresentations(formDataWithRepresentation, XtaMessageTestFactory.PRIMARY_FORM_DATA_MESSAGE);
var baseAssert = assertThat(result.getControl().getRepresentations()).isPresent().get();
baseAssert.extracting(Representations::getPrimaryFormDataRepresentation).isEqualTo(XtaMessageTestFactory.PRIMARY_FORM_DATA_MESSAGE);
baseAssert.extracting(Representations::getPrimaryFormDataPdfRepresentation).isEqualTo("PDF_FILE");
}
}
@DisplayName("process semantik")
@Nested
class TestProcessSemantik {
......