From 6ac79b3fe49d5d45e31f2ebbe8db43ca5c3d485c Mon Sep 17 00:00:00 2001
From: OZGCloud <ozgcloud@mgm-tp.com>
Date: Tue, 16 Apr 2024 09:30:42 +0200
Subject: [PATCH] OZG-5322 add test for BescheidEventListener

---
 .../bescheid/BescheidEventListener.java       |  29 ++-
 .../attacheditem/AttachedItemService.java     |   2 +-
 .../SmartDocumentsBescheidRemoteService.java  |   2 +
 .../bescheid/BescheidEventListenerITCase.java | 176 ++++++++++++++++++
 4 files changed, 193 insertions(+), 16 deletions(-)
 create mode 100644 vorgang-manager-server/src/test/java/de/ozgcloud/bescheid/BescheidEventListenerITCase.java

diff --git a/bescheid-manager/src/main/java/de/ozgcloud/bescheid/BescheidEventListener.java b/bescheid-manager/src/main/java/de/ozgcloud/bescheid/BescheidEventListener.java
index 2116b9a5e..b98ce1eb2 100644
--- a/bescheid-manager/src/main/java/de/ozgcloud/bescheid/BescheidEventListener.java
+++ b/bescheid-manager/src/main/java/de/ozgcloud/bescheid/BescheidEventListener.java
@@ -113,21 +113,6 @@ class BescheidEventListener {
 		return smartDocumentsProperties.filter(configuredForKiel).isPresent();
 	}
 
-	BescheidRequest createRequest(Command command) {
-		var eventBody = command.getBodyObject();
-		var builder = BescheidRequest.builder();
-
-		builder.vorgangId(VorgangId.from(command.getVorgangId()));
-		Optional.ofNullable(eventBody.get(BESCHEID_VOM_BODYKEY))
-				.map(String.class::cast).map(LocalDate::parse).ifPresent(builder::bescheidVom);
-		Optional.ofNullable(eventBody.get(GENEHMIGT_BODYKEY))
-				.map(Object::toString).map(Boolean::valueOf)
-				.ifPresentOrElse(builder::genehmigt, () -> builder.genehmigt(true));
-		builder.createFor(userService.getUserProfile());
-
-		return builder.build();
-	}
-
 	@EventListener(condition = IS_DELETE_BESCHEID)
 	public void onDeleteBescheid(CommandCreatedEvent event) {
 		runWithSecurityContext(event.getSource(), this::doDeleteBescheid);
@@ -164,6 +149,20 @@ class BescheidEventListener {
 		return fileService.uploadBescheidFile(bescheid);
 	}
 
+	BescheidRequest createRequest(Command command) {
+		var eventBody = command.getBodyObject();
+		var builder = BescheidRequest.builder();
+
+		builder.vorgangId(VorgangId.from(command.getVorgangId()));
+		Optional.ofNullable(eventBody.get(BESCHEID_VOM_BODYKEY))
+				.map(String.class::cast).map(LocalDate::parse).ifPresent(builder::bescheidVom);
+		Optional.ofNullable(eventBody.get(GENEHMIGT_BODYKEY))
+				.map(Object::toString).map(Boolean::valueOf)
+				.ifPresentOrElse(builder::genehmigt, () -> builder.genehmigt(true));
+		builder.createFor(userService.getUserProfile());
+
+		return builder.build();
+	}
 
 	void runWithSecurityContext(Command command, Consumer<Command> commandExecutor) {
 		SecurityContext prevContext = null;
diff --git a/bescheid-manager/src/main/java/de/ozgcloud/bescheid/attacheditem/AttachedItemService.java b/bescheid-manager/src/main/java/de/ozgcloud/bescheid/attacheditem/AttachedItemService.java
index 53e246ff9..a0a02756f 100644
--- a/bescheid-manager/src/main/java/de/ozgcloud/bescheid/attacheditem/AttachedItemService.java
+++ b/bescheid-manager/src/main/java/de/ozgcloud/bescheid/attacheditem/AttachedItemService.java
@@ -47,7 +47,7 @@ import lombok.extern.log4j.Log4j2;
 @Log4j2
 public class AttachedItemService {
 
-	static final String BESCHEID_ITEM_NAME = "Bescheid";
+	public static final String BESCHEID_ITEM_NAME = "Bescheid";
 	static final String CREATE_ATTACHED_ITEM_ORDER = "CREATE_ATTACHED_ITEM";
 	static final String UPDATE_ATTACHED_ITEM_ORDER = "UPDATE_ATTACHED_ITEM";
 	static final String DELETE_ATTACHED_ITEM = "DELETE_ATTACHED_ITEM";
diff --git a/bescheid-manager/src/main/java/de/ozgcloud/bescheid/smartdocuments/SmartDocumentsBescheidRemoteService.java b/bescheid-manager/src/main/java/de/ozgcloud/bescheid/smartdocuments/SmartDocumentsBescheidRemoteService.java
index 6dd87bd4b..664f4300d 100644
--- a/bescheid-manager/src/main/java/de/ozgcloud/bescheid/smartdocuments/SmartDocumentsBescheidRemoteService.java
+++ b/bescheid-manager/src/main/java/de/ozgcloud/bescheid/smartdocuments/SmartDocumentsBescheidRemoteService.java
@@ -14,6 +14,7 @@ import javax.xml.xpath.XPathFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Qualifier;
 import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.context.annotation.Primary;
 import org.springframework.http.HttpStatusCode;
 import org.springframework.http.MediaType;
 import org.springframework.stereotype.Service;
@@ -49,6 +50,7 @@ import reactor.core.publisher.Mono;
 
 @Log4j2
 @Service
+@Primary
 @ConditionalOnProperty("ozgcloud.bescheid.smart-documents.url")
 class SmartDocumentsBescheidRemoteService implements BescheidRemoteService {
 
diff --git a/vorgang-manager-server/src/test/java/de/ozgcloud/bescheid/BescheidEventListenerITCase.java b/vorgang-manager-server/src/test/java/de/ozgcloud/bescheid/BescheidEventListenerITCase.java
new file mode 100644
index 000000000..d1eb5639c
--- /dev/null
+++ b/vorgang-manager-server/src/test/java/de/ozgcloud/bescheid/BescheidEventListenerITCase.java
@@ -0,0 +1,176 @@
+/*
+ * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den
+ * Ministerpräsidenten des Landes Schleswig-Holstein
+ * Staatskanzlei
+ * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung
+ *
+ * Lizenziert unter der EUPL, Version 1.2 oder - sobald
+ * diese von der Europäischen Kommission genehmigt wurden -
+ * Folgeversionen der EUPL ("Lizenz");
+ * Sie dürfen dieses Werk ausschließlich gemäß
+ * dieser Lizenz nutzen.
+ * Eine Kopie der Lizenz finden Sie hier:
+ *
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
+ *
+ * Sofern nicht durch anwendbare Rechtsvorschriften
+ * gefordert oder in schriftlicher Form vereinbart, wird
+ * die unter der Lizenz verbreitete Software "so wie sie
+ * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN -
+ * ausdrücklich oder stillschweigend - verbreitet.
+ * Die sprachspezifischen Genehmigungen und Beschränkungen
+ * unter der Lizenz sind dem Lizenztext zu entnehmen.
+ */
+package de.ozgcloud.bescheid;
+
+import static de.ozgcloud.bescheid.BescheidEventListener.*;
+import static org.assertj.core.api.Assertions.*;
+import static org.mockito.Mockito.*;
+
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+
+import org.awaitility.Awaitility;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Captor;
+import org.mockito.Mock;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.boot.test.mock.mockito.MockBean;
+import org.springframework.boot.test.mock.mockito.SpyBean;
+import org.springframework.context.ApplicationEventPublisher;
+import org.springframework.context.event.EventListener;
+import org.springframework.data.mongodb.core.MongoOperations;
+import org.springframework.data.mongodb.core.query.Criteria;
+import org.springframework.data.mongodb.core.query.Query;
+import org.springframework.data.mongodb.gridfs.GridFsTemplate;
+import org.springframework.test.annotation.DirtiesContext;
+
+import com.mongodb.client.gridfs.model.GridFSFile;
+
+import de.ozgcloud.apilib.common.command.grpc.CommandMapper;
+import de.ozgcloud.bescheid.attacheditem.AttachedItemService;
+import de.ozgcloud.bescheid.attacheditem.BescheidItem;
+import de.ozgcloud.bescheid.common.callcontext.CallContextUser;
+import de.ozgcloud.bescheid.common.callcontext.CurrentUserService;
+import de.ozgcloud.bescheid.common.callcontext.UserProfile;
+import de.ozgcloud.command.CommandCreatedEvent;
+import de.ozgcloud.common.test.DataITCase;
+import de.ozgcloud.document.BescheidDocumentCreatedEvent;
+import de.ozgcloud.document.Document;
+import de.ozgcloud.vorgang.VorgangManagerServerApplication;
+import de.ozgcloud.vorgang.attached_item.VorgangAttachedItem;
+import de.ozgcloud.vorgang.attached_item.VorgangAttachedItemTestFactory;
+import de.ozgcloud.vorgang.command.CommandTestFactory;
+import de.ozgcloud.vorgang.vorgang.Vorgang;
+import de.ozgcloud.vorgang.vorgang.VorgangTestFactory;
+
+@SpringBootTest(classes = VorgangManagerServerApplication.class, properties = {
+		"grpc.server.inProcessName=test",
+		"grpc.server.port=-1",
+		"grpc.client.ozgcloud-command-manager.address=in-process:test",
+		"grpc.client.vorgang-manager.address=in-process:test",
+})
+@DataITCase
+@DirtiesContext
+class BescheidEventListenerITCase {
+
+	@Autowired
+	private ApplicationEventPublisher eventPublisher;
+	@SpyBean
+	private BescheidEventListener eventListener;
+	@SpyBean
+	private TestEventListener bescheidDocumentCreatedEventListener;
+	@Autowired
+	private CommandMapper mapper;
+
+	@Autowired
+	private MongoOperations mongoOperations;
+	@Autowired
+	private GridFsTemplate gridFsTemplate;
+
+	@MockBean
+	private CurrentUserService currentUserService;
+	@Mock
+	private CallContextUser callContextUser;
+	@Mock
+	private UserProfile userProfile;
+
+	@Captor
+	private ArgumentCaptor<BescheidDocumentCreatedEvent> bescheidDocumentCreatedEventCaptor;
+
+	@BeforeEach
+	void init() {
+		mongoOperations.dropCollection(VorgangAttachedItem.COLLECTION_NAME);
+		mongoOperations.dropCollection(Vorgang.COLLECTION_NAME);
+		when(currentUserService.getUser()).thenReturn(callContextUser);
+		when(currentUserService.getUserProfile()).thenReturn(userProfile);
+	}
+
+	@Test
+	void shouldCreateBescheidDocument() {
+		var vorgangId = mongoOperations.save(VorgangTestFactory.createBuilder().id(null).build()).getId();
+		var bescheidItemId = mongoOperations.save(createBescheidAttachedItem(vorgangId)).getId();
+
+		eventPublisher.publishEvent(buildCommandCreatedEvent(vorgangId, bescheidItemId));
+
+		Awaitility.await().atMost(60, TimeUnit.SECONDS).untilAsserted(() -> {
+			verify(bescheidDocumentCreatedEventListener).onBescheidDocumentCreated(bescheidDocumentCreatedEventCaptor.capture());
+			var bescheidDocument = getBescheidDocument();
+			assertThat(bescheidDocument).isNotNull();
+		});
+	}
+
+	@Test
+	void shouldCreateDocumentFile() {
+		var vorgangId = mongoOperations.save(VorgangTestFactory.createBuilder().id(null).build()).getId();
+		var bescheidItemId = mongoOperations.save(createBescheidAttachedItem(vorgangId)).getId();
+
+		eventPublisher.publishEvent(buildCommandCreatedEvent(vorgangId, bescheidItemId));
+
+		Awaitility.await().atMost(60, TimeUnit.SECONDS).untilAsserted(() -> {
+			verify(bescheidDocumentCreatedEventListener).onBescheidDocumentCreated(bescheidDocumentCreatedEventCaptor.capture());
+			assertThat(getBescheidDocumentFile()).isNotNull();
+		});
+	}
+
+	private VorgangAttachedItem createBescheidAttachedItem(String vorgangId) {
+		return VorgangAttachedItemTestFactory.createBuilder()
+				.id(null)
+				.version(0L)
+				.vorgangId(vorgangId)
+				.itemName(AttachedItemService.BESCHEID_ITEM_NAME)
+				.item(Map.of(BescheidItem.FIELD_STATUS, BescheidItem.Status.DRAFT.name()))
+				.build();
+	}
+
+	private CommandCreatedEvent buildCommandCreatedEvent(String vorgangId, String bescheidItemId) {
+		var command= CommandTestFactory.createBuilder()
+				.vorgangId(vorgangId)
+				.relationId(bescheidItemId)
+				.order(BescheidEventListener.CREATE_BESCHEID_DOCUMENT_ORDER)
+				.bodyObject(Map.of(BESCHEID_VOM_BODYKEY, "2024-01-01",
+						GENEHMIGT_BODYKEY, true))
+				.build();
+		return new CommandCreatedEvent(command);
+	}
+
+	private VorgangAttachedItem getBescheidDocument() {
+		var documentId = bescheidDocumentCreatedEventCaptor.getValue().getCreatedResource();
+		return mongoOperations.findById(documentId, VorgangAttachedItem.class);
+	}
+
+	private GridFSFile getBescheidDocumentFile() {
+		var fileId = getBescheidDocument().getItem().get(Document.FIELD_DOCUMENT_FILE).toString();
+		return gridFsTemplate.findOne(Query.query(Criteria.where("_id").is(fileId)));
+	}
+
+	static class TestEventListener {
+
+		@EventListener
+		public void onBescheidDocumentCreated(BescheidDocumentCreatedEvent event) {
+		}
+	}
+}
-- 
GitLab