From 95b33bd68a039ae57200e82a935f2bc3da90dd96 Mon Sep 17 00:00:00 2001
From: OZGCloud <ozgcloud@mgm-tp.com>
Date: Wed, 4 Dec 2024 19:47:11 +0100
Subject: [PATCH] OZG-6810 refactor MessageAttachmentService

---
 .../osi/MessageAttachmentService.java         |  58 ++---
 .../osi/MessageAttachmentServiceTest.java     | 207 ++++++++++++++----
 2 files changed, 193 insertions(+), 72 deletions(-)

diff --git a/nachrichten-manager-server/src/main/java/de/ozgcloud/nachrichten/postfach/osi/MessageAttachmentService.java b/nachrichten-manager-server/src/main/java/de/ozgcloud/nachrichten/postfach/osi/MessageAttachmentService.java
index c6c2170..16924f1 100644
--- a/nachrichten-manager-server/src/main/java/de/ozgcloud/nachrichten/postfach/osi/MessageAttachmentService.java
+++ b/nachrichten-manager-server/src/main/java/de/ozgcloud/nachrichten/postfach/osi/MessageAttachmentService.java
@@ -23,66 +23,66 @@
  */
 package de.ozgcloud.nachrichten.postfach.osi;
 
-import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.nio.charset.Charset;
 import java.util.Base64;
 
 import org.apache.commons.io.IOUtils;
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
 import de.ozgcloud.common.errorhandling.TechnicalException;
-import de.ozgcloud.nachrichten.postfach.AttachmentFile;
-import de.ozgcloud.nachrichten.postfach.BinaryFileService;
+import de.ozgcloud.nachrichten.file.AttachmentFile;
+import de.ozgcloud.nachrichten.file.AttachmentFileService;
 import de.ozgcloud.nachrichten.postfach.FileId;
-import de.ozgcloud.nachrichten.postfach.PersistPostfachNachrichtService;
-import lombok.val;
+import lombok.RequiredArgsConstructor;
 
 @Service
+@RequiredArgsConstructor
 public class MessageAttachmentService {
 
-	@Autowired
-	private PersistPostfachNachrichtService persistPostfachNachrichtService;
-
-	@Autowired
-	private BinaryFileService binaryFileService;
+	private final AttachmentFileService attachmentFileService;
 
 	public MessageAttachment getMessageAttachment(FileId fileId) {
+		return buildMessageAttachment(attachmentFileService.getFile(fileId), getAttachmentContent(fileId));
+	}
+
+	MessageAttachment buildMessageAttachment(AttachmentFile attachmentFile, String attachmentContent) {
+		return MessageAttachment.builder()
+				.fileName(attachmentFile.getName())
+				.content(attachmentContent)
+				.build();
+	}
+
+	String getAttachmentContent(FileId fileId) {
+		return encodeAttachmentContent(getContent(fileId));
+	}
+
+	byte[] getContent(FileId fileId) {
 		try {
-			val metadata = binaryFileService.getFile(fileId).getMetadata();
-			return MessageAttachment.builder()
-					.fileName(metadata.getString("name"))
-					.content(getAttachmentContent(fileId))
-					.build();
+			return IOUtils.toByteArray(attachmentFileService.getFileContent(fileId));
 		} catch (IOException e) {
-			throw new TechnicalException(e.getMessage(), e);
+			throw new TechnicalException("Cannot get file content", e);
 		}
 	}
 
-	String getAttachmentContent(FileId fileId) throws IOException {
-		ByteArrayOutputStream contentStream = new ByteArrayOutputStream();
-		IOUtils.copy(getAttachmentContentStream(fileId), contentStream);
-		return encodeAttachmentContent(contentStream.toByteArray());
-	}
-
-	private String encodeAttachmentContent(byte[] content) {
+	String encodeAttachmentContent(byte[] content) {
 		return new String(Base64.getEncoder().encode(content));
 	}
 
 	public String persistAttachment(String vorgangId, MessageAttachment attachment) {
-		return persistPostfachNachrichtService.persistAttachment(vorgangId, mapAttachmentFile(attachment));
+		return attachmentFileService.createAttachmentFile(buildAttachmentFile(vorgangId, attachment), getContent(attachment));
 	}
 
-	AttachmentFile mapAttachmentFile(MessageAttachment attachment) {
+	AttachmentFile buildAttachmentFile(String vorgangId, MessageAttachment attachment) {
 		return AttachmentFile.builder()
 				.name(attachment.getFileName())
-				.content(() -> IOUtils.toInputStream(attachment.getContent(), Charset.defaultCharset())).build();
+				.vorgangId(vorgangId)
+				.build();
 	}
 
-	InputStream getAttachmentContentStream(FileId fileId) {
-		return binaryFileService.getUploadedFileStream(fileId);
+	InputStream getContent(MessageAttachment attachment) {
+		return IOUtils.toInputStream(attachment.getContent(), Charset.defaultCharset());
 	}
 
 }
diff --git a/nachrichten-manager-server/src/test/java/de/ozgcloud/nachrichten/postfach/osi/MessageAttachmentServiceTest.java b/nachrichten-manager-server/src/test/java/de/ozgcloud/nachrichten/postfach/osi/MessageAttachmentServiceTest.java
index dc473e1..89a19c3 100644
--- a/nachrichten-manager-server/src/test/java/de/ozgcloud/nachrichten/postfach/osi/MessageAttachmentServiceTest.java
+++ b/nachrichten-manager-server/src/test/java/de/ozgcloud/nachrichten/postfach/osi/MessageAttachmentServiceTest.java
@@ -28,104 +28,225 @@ import static org.mockito.ArgumentMatchers.*;
 import static org.mockito.Mockito.*;
 
 import java.io.ByteArrayInputStream;
-import java.io.IOException;
 import java.io.InputStream;
-import java.sql.Date;
-import java.time.Instant;
 
-import org.bson.BsonObjectId;
-import org.bson.BsonValue;
-import org.bson.Document;
 import org.junit.jupiter.api.BeforeEach;
 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 com.mongodb.client.gridfs.model.GridFSFile;
+import com.thedeanda.lorem.LoremIpsum;
 
-import de.ozgcloud.nachrichten.postfach.BinaryFileService;
+import de.ozgcloud.nachrichten.file.AttachmentFile;
+import de.ozgcloud.nachrichten.file.AttachmentFileService;
+import de.ozgcloud.nachrichten.file.AttachmentFileTestFactory;
 import de.ozgcloud.nachrichten.postfach.FileId;
 
 class MessageAttachmentServiceTest {
-	private static final FileId FILE_ID = FileId.from("42");
 
+	private static final FileId FILE_ID = FileId.from(LoremIpsum.getInstance().getWords(1));
+
+	@Spy
 	@InjectMocks
-	private MessageAttachmentService messageAttachmentService;
+	private MessageAttachmentService service;
 
 	@Mock
-	private BinaryFileService fileService;
-
-	private GridFSFile gridFsfile;
+	private AttachmentFileService attachmentFileService;
 
 	@Nested
-	class TestLoadingAttachment {
+	class TestGetMessageAttachment {
+
+		@Mock
+		private AttachmentFile attachmentFile;
+		@Mock
+		private MessageAttachment messageAttachment;
+
 		@BeforeEach
 		void init() {
-			Document metadata = new Document();
-			metadata.put("name", MessageAttachmentTestFactory.FILENAME);
-			BsonValue id = new BsonObjectId();
-			gridFsfile = new GridFSFile(id, FILE_ID.toString(), 0, 0, Date.from(Instant.now()), metadata);
+			when(attachmentFileService.getFile(any())).thenReturn(attachmentFile);
+			doReturn(MessageAttachmentTestFactory.CONTENT).when(service).getAttachmentContent(any());
+			doReturn(messageAttachment).when(service).buildMessageAttachment(any(), any());
+		}
 
-			when(fileService.getFile(any())).thenReturn(gridFsfile);
-			when(fileService.getUploadedFileStream(any()))
-					.thenReturn(new ByteArrayInputStream(MessageAttachmentTestFactory.DECODED_CONTENT.getBytes()));
+		@Test
+		void shouldCallGetFile() {
+			getMessageAttachment();
+
+			verify(attachmentFileService).getFile(FILE_ID);
 		}
 
 		@Test
-		void shouldHaveAttachmentWithFileName() {
-			MessageAttachment attachment = messageAttachmentService.getMessageAttachment(FILE_ID);
+		void shouldCallGetAttachmentContent() {
+			getMessageAttachment();
 
-			assertThat(attachment.getFileName()).isEqualTo(MessageAttachmentTestFactory.FILENAME);
+			verify(service).getAttachmentContent(FILE_ID);
 		}
 
 		@Test
-		void shouldHaveAttachmentContent() {
-			MessageAttachment attachment = messageAttachmentService.getMessageAttachment(FILE_ID);
+		void shouldCallBuildMessageAttachment() {
+			getMessageAttachment();
 
-			assertThat(attachment.getContent()).isEqualTo(MessageAttachmentTestFactory.CONTENT);
+			verify(service).buildMessageAttachment(attachmentFile, MessageAttachmentTestFactory.CONTENT);
 		}
 
+		@Test
+		void shouldReturnMessageAttachment() {
+			var result = getMessageAttachment();
+
+			assertThat(result).isSameAs(messageAttachment);
+		}
+
+		private MessageAttachment getMessageAttachment() {
+			return service.getMessageAttachment(FILE_ID);
+		}
 	}
 
 	@Nested
-	class TestLoadingAttachmentContent {
+	class TestBuildMessageAttachment {
+
+		@Test
+		void shouldBuildMessageAttachment() {
+			var attachment = buildMessageAttachment();
+
+			assertThat(attachment).usingRecursiveComparison().isEqualTo(MessageAttachmentTestFactory.create());
+		}
+
+		private MessageAttachment buildMessageAttachment() {
+			return service.buildMessageAttachment(AttachmentFileTestFactory.create(), MessageAttachmentTestFactory.CONTENT);
+		}
+	}
+
+	@Nested
+	class TestGetAttachmentContent {
+
+		private static final byte[] CONTENT = MessageAttachmentTestFactory.CONTENT.getBytes();
+
 		@BeforeEach
 		void init() {
-			when(fileService.getUploadedFileStream(any()))
-					.thenReturn(new ByteArrayInputStream(MessageAttachmentTestFactory.DECODED_CONTENT.getBytes()));
+			doReturn(CONTENT).when(service).getContent(any(FileId.class));
+			doReturn(MessageAttachmentTestFactory.CONTENT).when(service).encodeAttachmentContent(any());
 		}
 
 		@Test
-		void shouldGetInputStream() {
-			InputStream input = messageAttachmentService.getAttachmentContentStream(FILE_ID);
+		void shouldCallGetContent() {
+			service.getAttachmentContent(FILE_ID);
 
-			assertThat(input).isNotNull();
+			verify(service).getContent(FILE_ID);
 		}
 
 		@Test
-		void shouldGetContent() throws IOException {
-			String input = messageAttachmentService.getAttachmentContent(FILE_ID);
+		void shouldCallEncodeAttachmentContent() {
+			service.getAttachmentContent(FILE_ID);
 
-			assertThat(input).isEqualTo(MessageAttachmentTestFactory.CONTENT);
+			verify(service).encodeAttachmentContent(CONTENT);
+		}
+
+		@Test
+		void shouldReturnContent() {
+			var result = service.getAttachmentContent(FILE_ID);
+
+			assertThat(result).isEqualTo(MessageAttachmentTestFactory.CONTENT);
 		}
 	}
 
 	@Nested
-	class TestMapAttachmentFile {
+	class TestGetContent {
 
 		@Test
-		void shouldMapFileName() {
-			var attachmentFile = messageAttachmentService.mapAttachmentFile(MessageAttachmentTestFactory.create());
+		void shouldCallGetFileContent() {
+			when(attachmentFileService.getFileContent(any())).thenReturn(new ByteArrayInputStream(MessageAttachmentTestFactory.CONTENT.getBytes()));
+
+			service.getContent(FILE_ID);
+
+			verify(attachmentFileService).getFileContent(FILE_ID);
+		}
+
+		@Test
+		void shouldReturnContent() {
+			when(attachmentFileService.getFileContent(any())).thenReturn(new ByteArrayInputStream(MessageAttachmentTestFactory.CONTENT.getBytes()));
+
+			var result = service.getContent(FILE_ID);
+
+			assertThat(result).isEqualTo(MessageAttachmentTestFactory.CONTENT.getBytes());
+		}
+	}
 
-			assertThat(attachmentFile.getName()).isEqualTo(MessageAttachmentTestFactory.FILENAME);
+	@Nested
+	class TestEncodeAttachmentContent {
+
+		@Test
+		void shouldEncodeContent() {
+			var result = service.encodeAttachmentContent(MessageAttachmentTestFactory.DECODED_CONTENT.getBytes());
+
+			assertThat(result).isEqualTo(MessageAttachmentTestFactory.CONTENT);
+		}
+	}
+
+	@Nested
+	class TestPersistAttachment {
+
+		private static final String ATTACHMENT_FILE_ID = LoremIpsum.getInstance().getWords(1);
+		private static final MessageAttachment ATTACHMENT = MessageAttachmentTestFactory.create();
+
+		@Mock
+		private AttachmentFile attachmentFile;
+		@Mock
+		private InputStream inputStream;
+
+		@BeforeEach
+		void init() {
+			doReturn(attachmentFile).when(service).buildAttachmentFile(any(), any());
+			doReturn(inputStream).when(service).getContent(any(MessageAttachment.class));
+			when(attachmentFileService.createAttachmentFile(any(), any())).thenReturn(ATTACHMENT_FILE_ID);
 		}
 
 		@Test
-		void shouldMapContent() {
-			var attachmentFile = messageAttachmentService.mapAttachmentFile(MessageAttachmentTestFactory.create());
+		void shouldCallMapAttachmentFile() {
+			persistAttachment();
+
+			verify(service).buildAttachmentFile(AttachmentFileTestFactory.VORGANG_ID, ATTACHMENT);
+		}
+
+		@Test
+		void shouldCallGetContent() {
+			persistAttachment();
+
+			verify(service).getContent(ATTACHMENT);
+		}
+
+		@Test
+		void shouldCallCreateAttachmentFile() {
+			persistAttachment();
+
+			verify(attachmentFileService).createAttachmentFile(attachmentFile, inputStream);
+		}
+
+		@Test
+		void shouldReturnAttachmentFileId() {
+			var result = persistAttachment();
+
+			assertThat(result).isEqualTo(ATTACHMENT_FILE_ID);
+		}
+
+		private String persistAttachment() {
+			return service.persistAttachment(AttachmentFileTestFactory.VORGANG_ID, ATTACHMENT);
+		}
+	}
+
+	@Nested
+	class TestBuildAttachmentFile {
+
+		@Test
+		void shouldMapFileName() {
+			var attachmentFile = buildAttachmentFile();
+
+			assertThat(attachmentFile).usingRecursiveComparison().ignoringFields("contentType").isEqualTo(AttachmentFileTestFactory.create());
+		}
 
-			assertThat(attachmentFile.getContent()).hasContent(MessageAttachmentTestFactory.CONTENT);
+		private AttachmentFile buildAttachmentFile() {
+			return service.buildAttachmentFile(AttachmentFileTestFactory.VORGANG_ID, MessageAttachmentTestFactory.create());
 		}
 	}
 }
-- 
GitLab