diff --git a/alfa-service/src/main/java/de/ozgcloud/alfa/bescheid/BescheidHistorieProcessor.java b/alfa-service/src/main/java/de/ozgcloud/alfa/bescheid/BescheidHistorieProcessor.java index 06f71be59ea10d9874401bf59c538229ca3d18f7..bc3ba70897c28c7f9780b87f85d69ce126f3f5fd 100644 --- a/alfa-service/src/main/java/de/ozgcloud/alfa/bescheid/BescheidHistorieProcessor.java +++ b/alfa-service/src/main/java/de/ozgcloud/alfa/bescheid/BescheidHistorieProcessor.java @@ -26,6 +26,7 @@ package de.ozgcloud.alfa.bescheid; import java.util.Comparator; import java.util.List; import java.util.Map; +import java.util.Set; import java.util.function.Predicate; import java.util.stream.Stream; @@ -48,43 +49,34 @@ class BescheidHistorieProcessor implements HistorieProcessor { private final VorgangAttachedItemService vorgangAttachedItemService; - private static final Predicate<Command> IS_NOT_CREATE_BESCHEID_COMMAND = Predicate - .not(command -> command.getCommandOrder() == CommandOrder.CREATE_BESCHEID); - private static final Predicate<Command> IS_NOT_DELETE_BESCHEID_COMMAND = Predicate - .not(command -> command.getCommandOrder() == CommandOrder.DELETE_BESCHEID); - private static final Predicate<Command> IS_UPDATE_BESCHEID_COMMAND = command -> command.getCommandOrder() == CommandOrder.UPDATE_BESCHEID; + private static final Set<CommandOrder> BESCHEID_ORDER_TO_REMOVE = Set.of(CommandOrder.CREATE_BESCHEID, CommandOrder.DELETE_BESCHEID); + private static final Predicate<Command> IS_NOT_BESCHEID_ORDER_TO_REMOVE = Predicate + .not(command -> BESCHEID_ORDER_TO_REMOVE.contains(command.getCommandOrder())); + private static final Set<CommandOrder> VORGANG_ATTACHED_ITEM_ORDER_TO_REMOVE = Set.of(CommandOrder.CREATE_ATTACHED_ITEM, + CommandOrder.UPDATE_ATTACHED_ITEM, CommandOrder.PATCH_ATTACHED_ITEM); private static final Predicate<Command> IS_BESCHEID_ATTACHED_ITEM = command -> BESCHEID_ITEM_NAME .equals(MapUtils.getString(command.getBody(), VorgangAttachedItem.FIELD_ITEM_NAME, StringUtils.EMPTY)); - private static final Predicate<Command> IS_NOT_CREATE_ATTACHED_ITEM = Predicate - .not(command -> command.getCommandOrder() == CommandOrder.CREATE_ATTACHED_ITEM - && IS_BESCHEID_ATTACHED_ITEM.test(command)); - private static final Predicate<Command> IS_NOT_UPDATE_ATTACHED_ITEM = Predicate - .not(command -> command.getCommandOrder() == CommandOrder.UPDATE_ATTACHED_ITEM - && IS_BESCHEID_ATTACHED_ITEM.test(command)); - private static final Predicate<Command> IS_NOT_PATCH_ATTACHED_ITEM = Predicate - .not(command -> command.getCommandOrder() == CommandOrder.PATCH_ATTACHED_ITEM - && IS_BESCHEID_ATTACHED_ITEM.test(command)); + private static final Predicate<Command> IS_NOT_VORGANG_ATTACHED_BESCHEID_ITEM_ORDER_TO_REMOVE = Predicate + .not(command -> VORGANG_ATTACHED_ITEM_ORDER_TO_REMOVE.contains(command.getCommandOrder()) && IS_BESCHEID_ATTACHED_ITEM.test(command)); + + private static final Predicate<Command> IS_UPDATE_BESCHEID_COMMAND = command -> command.getCommandOrder() == CommandOrder.UPDATE_BESCHEID; @Override - public List<Command> process(List<Command> commands) { - var relevantCommands = filterByOrder(commands); + public Stream<Command> process(Stream<Command> commands) { + var relevantCommands = filterByOrder(commands).toList(); return filterBescheidRelatedCommands(relevantCommands); } - List<Command> filterByOrder(List<Command> commands) { - return commands.stream() - .filter(IS_NOT_CREATE_BESCHEID_COMMAND) - .filter(IS_NOT_DELETE_BESCHEID_COMMAND) - .filter(IS_NOT_CREATE_ATTACHED_ITEM) - .filter(IS_NOT_UPDATE_ATTACHED_ITEM) - .filter(IS_NOT_PATCH_ATTACHED_ITEM) - .toList(); + Stream<Command> filterByOrder(Stream<Command> commands) { + return commands + .filter(IS_NOT_BESCHEID_ORDER_TO_REMOVE) + .filter(IS_NOT_VORGANG_ATTACHED_BESCHEID_ITEM_ORDER_TO_REMOVE); } - List<Command> filterBescheidRelatedCommands(List<Command> commands) { + Stream<Command> filterBescheidRelatedCommands(List<Command> commands) { var excludeCommandIds = getExcludedBescheidRelatedCommandIds(commands); - return commands.stream().filter(command -> !excludeCommandIds.contains(command.getId())).toList(); + return commands.stream().filter(command -> !excludeCommandIds.contains(command.getId())); } List<String> getExcludedBescheidRelatedCommandIds(List<Command> commands) { diff --git a/alfa-service/src/main/java/de/ozgcloud/alfa/bescheid/DocumentHistorieProcessor.java b/alfa-service/src/main/java/de/ozgcloud/alfa/bescheid/DocumentHistorieProcessor.java index 028aa66f2141bf2084692ef4ca20904a5edc709d..616c96c686d2344d4199ca1158960aa892842ef7 100644 --- a/alfa-service/src/main/java/de/ozgcloud/alfa/bescheid/DocumentHistorieProcessor.java +++ b/alfa-service/src/main/java/de/ozgcloud/alfa/bescheid/DocumentHistorieProcessor.java @@ -23,8 +23,8 @@ */ package de.ozgcloud.alfa.bescheid; -import java.util.List; import java.util.function.Predicate; +import java.util.stream.Stream; import org.apache.commons.collections.MapUtils; import org.apache.commons.lang3.StringUtils; @@ -47,15 +47,16 @@ class DocumentHistorieProcessor implements HistorieProcessor { private static final Predicate<Command> IS_DOCUMENT_ATTACHED_ITEM = command -> DOCUMENT_ITEM_NAME .equals(MapUtils.getString(command.getBody(), VorgangAttachedItem.FIELD_ITEM_NAME, StringUtils.EMPTY)); - private static final Predicate<Command> IS_NOT_CREATE_ATTACHED_ITEM = command -> !(command.getCommandOrder() == CommandOrder.CREATE_ATTACHED_ITEM + private static final Predicate<Command> IS_NOT_CREATE_ATTACHED_DOCUMENT_ITEM = command -> !(command + .getCommandOrder() == CommandOrder.CREATE_ATTACHED_ITEM && IS_DOCUMENT_ATTACHED_ITEM.test(command)); @Override - public List<Command> process(List<Command> commands) { + public Stream<Command> process(Stream<Command> commands) { return filterIrrelevantCommands(commands); } - List<Command> filterIrrelevantCommands(List<Command> commands) { - return commands.stream().filter(IS_NOT_DOCUMENT_COMMAND).filter(IS_NOT_CREATE_ATTACHED_ITEM).toList(); + Stream<Command> filterIrrelevantCommands(Stream<Command> commands) { + return commands.filter(IS_NOT_DOCUMENT_COMMAND).filter(IS_NOT_CREATE_ATTACHED_DOCUMENT_ITEM); } } diff --git a/alfa-service/src/main/java/de/ozgcloud/alfa/common/attacheditem/VorgangAttachedItemHistorieProcessor.java b/alfa-service/src/main/java/de/ozgcloud/alfa/common/attacheditem/VorgangAttachedItemHistorieProcessor.java new file mode 100644 index 0000000000000000000000000000000000000000..ecbd3482e02823170ba6c0bfcb1b3a737fcabba7 --- /dev/null +++ b/alfa-service/src/main/java/de/ozgcloud/alfa/common/attacheditem/VorgangAttachedItemHistorieProcessor.java @@ -0,0 +1,22 @@ +package de.ozgcloud.alfa.common.attacheditem; + +import java.util.function.Predicate; +import java.util.stream.Stream; + +import org.springframework.stereotype.Component; + +import de.ozgcloud.alfa.common.command.Command; +import de.ozgcloud.alfa.common.command.CommandOrder; +import de.ozgcloud.alfa.historie.HistorieProcessor; + +@Component +class VorgangAttachedItemHistorieProcessor implements HistorieProcessor { + + private static final Predicate<Command> IS_NOT_DELETE_ATTACHED_ITEM = command -> CommandOrder.DELETE_ATTACHED_ITEM != command.getCommandOrder(); + + @Override + public Stream<Command> process(Stream<Command> commands) { + return commands.filter(IS_NOT_DELETE_ATTACHED_ITEM); + } + +} diff --git a/alfa-service/src/main/java/de/ozgcloud/alfa/historie/HistorieCommandHandler.java b/alfa-service/src/main/java/de/ozgcloud/alfa/historie/HistorieCommandHandler.java deleted file mode 100644 index 3da6312c0c7c5787c74fad6a9ba7270db2e15c52..0000000000000000000000000000000000000000 --- a/alfa-service/src/main/java/de/ozgcloud/alfa/historie/HistorieCommandHandler.java +++ /dev/null @@ -1,197 +0,0 @@ -/* - * Copyright (C) 2023 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.alfa.historie; - -import java.util.Map; -import java.util.Optional; -import java.util.function.Predicate; - -import org.apache.commons.collections.MapUtils; -import org.apache.commons.lang3.StringUtils; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; - -import de.ozgcloud.alfa.common.attacheditem.VorgangAttachedItem; -import de.ozgcloud.alfa.common.attacheditem.VorgangAttachedItemService; -import de.ozgcloud.alfa.common.command.Command; -import de.ozgcloud.alfa.common.command.CommandBodyMapper; -import de.ozgcloud.alfa.common.command.CommandOrder; -import de.ozgcloud.alfa.common.command.CommandService; -import de.ozgcloud.alfa.common.command.CommandStatus; -import de.ozgcloud.alfa.common.command.LegacyOrder; -import de.ozgcloud.alfa.kommentar.Kommentar; -import de.ozgcloud.alfa.loeschanforderung.DeleteLoeschAnforderung; -import de.ozgcloud.alfa.wiedervorlage.Wiedervorlage; - -/** - * Bitte zukuenftig als Implementierung von {@link HistorieProcessor} in den - * jeweiligen fachlichen packages umsetzen. - * - * TODO: Aktuellen Code auf Processoren umstellen - */ -@Component -class HistorieCommandHandler { - - static final String DIRECTION_INCOMMING = "IN"; - static final String DIRECTION_OUTGOING = "OUT"; - static final String DIRECTION = "direction"; - static final String OZGCLOUD_NACHRICHTEN_MANAGER = "OzgCloud_NachrichtenManager"; - static final String CLIENT = "client"; - - private static final Predicate<Command> IS_CREATE_ATTACHED_ITEM = command -> command.getCommandOrder() == CommandOrder.CREATE_ATTACHED_ITEM; - - @Autowired - private VorgangAttachedItemService vorgangAttachedItemService; - - @Autowired - private CommandService commandService; - - public boolean isHistorieCommand(Command command) { - return !isOutgoingPostfachNachrichtByOzgCloudNachrichtenManager(command) - && !isCreateLoeschAnforderungVorgangAttachedItem(command) - && !isLoeschAnforderungZuruecknehmenRevoked(command) - && !isDeleteVorgangAttachedItem(command); - } - - boolean isOutgoingPostfachNachrichtByOzgCloudNachrichtenManager(Command command) { - return command.getCommandOrder().equals(CommandOrder.CREATE_ATTACHED_ITEM) && isOzgCloudNachrichtenManager(command) && isOutgoing(command); - } - - private boolean isOzgCloudNachrichtenManager(Command command) { - return StringUtils.equals(MapUtils.getString(command.getBody(), CLIENT), OZGCLOUD_NACHRICHTEN_MANAGER); - } - - private boolean isOutgoing(Command command) { - return isDirection(command, DIRECTION_OUTGOING); - } - - boolean isCreateLoeschAnforderungVorgangAttachedItem(Command command) { - return Optional.of(command) - .filter(IS_CREATE_ATTACHED_ITEM) - .map(Command::getBody) - .map(bodyMap -> MapUtils.getString(bodyMap, VorgangAttachedItem.FIELD_ITEM_NAME)) - .map(vorgangAttachedItemService::isLoeschAnforderung) - .orElse(false); - } - - boolean isLoeschAnforderungZuruecknehmenRevoked(Command command) { - if (command.getCommandOrder() != CommandOrder.LOESCH_ANFORDERUNG_ZURUECKNEHMEN) { - return false; - } - var changeStatusCommand = commandService.getById(getChangeStatusCommandId(command)); - return changeStatusCommand.getStatus() == CommandStatus.REVOKED; - } - - private String getChangeStatusCommandId(Command command) { - return MapUtils.getString(command.getBody(), DeleteLoeschAnforderung.CHANGE_STATUS_COMMAND_ID_FIELD); - } - - boolean isDeleteVorgangAttachedItem(Command command) { - return command.getCommandOrder() == CommandOrder.DELETE_ATTACHED_ITEM; - } - - public Command translateOrder(Command command) { - HistorieCommandHandler translator = new HistorieCommandHandler(); - return switch (command.getCommandOrder()) { - case CREATE_ATTACHED_ITEM: - yield translator.mapCreateOrder(command); - case UPDATE_ATTACHED_ITEM: - yield translator.mapUpdateOrder(command); - case PATCH_ATTACHED_ITEM: - yield translator.mapPatchOrder(command); - case SEND_POSTFACH_MAIL: - yield command.toBuilder().order(CommandOrder.SEND_POSTFACH_NACHRICHT.name()).build(); - default: - yield command; - }; - } - - private Command mapCreateOrder(Command command) { - var resultBuilder = command.toBuilder(); - var itemName = getItemName(command); - - itemName.ifPresent(name -> { - if (name.equals(Kommentar.class.getSimpleName())) { - resultBuilder.order(LegacyOrder.CREATE_KOMMENTAR).build(); - } else if (name.equals(Wiedervorlage.class.getSimpleName())) { - resultBuilder.order(LegacyOrder.CREATE_WIEDERVORLAGE).build(); - } else if (isOzgCloudNachrichtenManager(command) && isIncomming(command)) { - resultBuilder.order(CommandOrder.RECEIVE_POSTFACH_NACHRICHT.name()).build(); - } - }); - - return resultBuilder.build(); - } - - private boolean isIncomming(Command command) { - return isDirection(command, DIRECTION_INCOMMING); - } - - private boolean isDirection(Command command, String expectedDirection) { - return StringUtils.equals(MapUtils.getString(getItemMap(command), DIRECTION), expectedDirection); - } - - private Command mapUpdateOrder(Command command) { - var resultBuilder = command.toBuilder(); - var itemName = getItemName(command); - - itemName.ifPresent(name -> { - if (name.equals(Kommentar.class.getSimpleName())) { - resultBuilder.order(LegacyOrder.EDIT_KOMMENTAR).build(); - } else if (name.equals(Wiedervorlage.class.getSimpleName())) { - resultBuilder.order(LegacyOrder.EDIT_WIEDERVORLAGE).build(); - } - }); - - return resultBuilder.build(); - } - - private Optional<String> getItemName(Command command) { - return Optional.ofNullable(MapUtils.getString(command.getBody(), CommandBodyMapper.ITEM_NAME_PROPERTY)); - } - - private Command mapPatchOrder(Command command) { - var resultBuilder = command.toBuilder(); - var isDone = getDoneValue(command); - - isDone.ifPresent(done -> { - if (done.booleanValue()) { - resultBuilder.order(LegacyOrder.WIEDERVORLAGE_ERLEDIGEN).build(); - } else { - resultBuilder.order(LegacyOrder.WIEDERVORLAGE_WIEDEREROEFFNEN).build(); - } - }); - - return resultBuilder.build(); - } - - private Optional<Boolean> getDoneValue(Command command) { - return Optional.ofNullable(MapUtils.getBoolean(getItemMap(command), Wiedervorlage.DONE_FIELD)); - } - - @SuppressWarnings("unchecked") - private Map<String, Object> getItemMap(Command command) { - return MapUtils.getMap(command.getBody(), CommandBodyMapper.ITEM_PROPERTY); - } -} \ No newline at end of file diff --git a/alfa-service/src/main/java/de/ozgcloud/alfa/historie/HistorieProcessor.java b/alfa-service/src/main/java/de/ozgcloud/alfa/historie/HistorieProcessor.java index e28cb6a96dcc9748fafd419e0acd4e5ec6b7e815..ce40562ed12f1396c40839dbb837130e1b636915 100644 --- a/alfa-service/src/main/java/de/ozgcloud/alfa/historie/HistorieProcessor.java +++ b/alfa-service/src/main/java/de/ozgcloud/alfa/historie/HistorieProcessor.java @@ -23,11 +23,11 @@ */ package de.ozgcloud.alfa.historie; -import java.util.List; +import java.util.stream.Stream; import de.ozgcloud.alfa.common.command.Command; public interface HistorieProcessor { - List<Command> process(List<Command> commands); + Stream<Command> process(Stream<Command> commands); } \ No newline at end of file diff --git a/alfa-service/src/main/java/de/ozgcloud/alfa/historie/HistorieService.java b/alfa-service/src/main/java/de/ozgcloud/alfa/historie/HistorieService.java index 28cf9b859c1b07fb16971ac69715067da0872691..89cee62e20fe8102680db68687af819b1df58bc2 100644 --- a/alfa-service/src/main/java/de/ozgcloud/alfa/historie/HistorieService.java +++ b/alfa-service/src/main/java/de/ozgcloud/alfa/historie/HistorieService.java @@ -23,18 +23,13 @@ */ package de.ozgcloud.alfa.historie; -import java.util.HashSet; import java.util.List; -import java.util.Set; import java.util.stream.Stream; -import org.apache.commons.collections.MapUtils; import org.springframework.stereotype.Service; import de.ozgcloud.alfa.common.command.Command; -import de.ozgcloud.alfa.common.command.CommandOrder; import de.ozgcloud.alfa.common.command.CommandService; -import de.ozgcloud.alfa.loeschanforderung.DeleteLoeschAnforderung; import lombok.RequiredArgsConstructor; @RequiredArgsConstructor @@ -42,55 +37,17 @@ import lombok.RequiredArgsConstructor; class HistorieService { private final CommandService commandService; - private final HistorieCommandHandler historieCommandHandler; private final List<HistorieProcessor> processors; public Stream<Command> findFinishedCommands(String vorgangId) { - var reduceBy = new HashSet<String>(); - var commands = commandService.findFinishedCommands(vorgangId) - .filter(historieCommandHandler::isHistorieCommand) - .map(command -> considerReduceByIds(reduceBy, command)) - .map(historieCommandHandler::translateOrder).toList(); - - commands = commands.stream().filter(command -> !reduceBy.contains(command.getId())) - .toList(); + var commands = commandService.findFinishedCommands(vorgangId); return processCommands(commands); } - private Stream<Command> processCommands(List<Command> commands) { - return new CommandHistorieProcessor().process(commands).stream(); - } - - class CommandHistorieProcessor { - private List<Command> processedCommands; - - public List<Command> process(List<Command> commands) { - processedCommands = commands; - processors.forEach(processor -> processedCommands = processor.process(processedCommands)); - return processedCommands; - } - } - - private Command considerReduceByIds(Set<String> reduceBy, Command command) { - if (isLoeschAnforderungZuruecknehmenCommand(command)) { - reduceBy.addAll(getCommandBodyIds(command)); + Stream<Command> processCommands(Stream<Command> commands) { + for (var processor : processors) { + commands = processor.process(commands); } - return command; - } - - private boolean isLoeschAnforderungZuruecknehmenCommand(Command command) { - return command.getCommandOrder() == CommandOrder.LOESCH_ANFORDERUNG_ZURUECKNEHMEN; - } - - private Set<String> getCommandBodyIds(Command command) { - return Set.of(getDeleteAttachedItemCommandId(command), getChangeStatusCommandId(command)); - } - - private String getDeleteAttachedItemCommandId(Command command) { - return MapUtils.getString(command.getBody(), DeleteLoeschAnforderung.DELETE_ATTACHED_ITEM_COMMAND_ID_FIELD); - } - - private String getChangeStatusCommandId(Command command) { - return MapUtils.getString(command.getBody(), DeleteLoeschAnforderung.CHANGE_STATUS_COMMAND_ID_FIELD); + return commands; } } \ No newline at end of file diff --git a/alfa-service/src/main/java/de/ozgcloud/alfa/kommentar/KommentarHistorieProcessor.java b/alfa-service/src/main/java/de/ozgcloud/alfa/kommentar/KommentarHistorieProcessor.java new file mode 100644 index 0000000000000000000000000000000000000000..06eda922582db8ab01d599e3f99db3aeca1ca2ac --- /dev/null +++ b/alfa-service/src/main/java/de/ozgcloud/alfa/kommentar/KommentarHistorieProcessor.java @@ -0,0 +1,53 @@ +package de.ozgcloud.alfa.kommentar; + +import java.util.Optional; +import java.util.stream.Stream; + +import org.apache.commons.collections.MapUtils; +import org.springframework.stereotype.Component; + +import de.ozgcloud.alfa.common.command.Command; +import de.ozgcloud.alfa.common.command.CommandBodyMapper; +import de.ozgcloud.alfa.common.command.CommandOrder; +import de.ozgcloud.alfa.common.command.LegacyOrder; +import de.ozgcloud.alfa.historie.HistorieProcessor; + +@Component +class KommentarHistorieProcessor implements HistorieProcessor { + + @Override + public Stream<Command> process(Stream<Command> commands) { + return commands.map(this::translateCreateKommentar).map(this::translateEditKommentar); + } + + Command translateCreateKommentar(Command command) { + if (isCreateAttachedItemCommand(command) && hasKommentarItemName(command)) { + return command.toBuilder().order(LegacyOrder.CREATE_KOMMENTAR).build(); + } + return command; + } + + private boolean isCreateAttachedItemCommand(Command command) { + return CommandOrder.CREATE_ATTACHED_ITEM == command.getCommandOrder(); + } + + Command translateEditKommentar(Command command) { + if (isUpdateAttachedItemCommand(command) && hasKommentarItemName(command)) { + return command.toBuilder().order(LegacyOrder.EDIT_KOMMENTAR).build(); + } + return command; + } + + private boolean isUpdateAttachedItemCommand(Command command) { + return CommandOrder.UPDATE_ATTACHED_ITEM == command.getCommandOrder(); + } + + private boolean hasKommentarItemName(Command command) { + return getItemName(command).filter(itemName -> Kommentar.class.getSimpleName().equals(itemName)).isPresent(); + } + + private Optional<String> getItemName(Command command) { + return Optional.ofNullable(MapUtils.getString(command.getBody(), CommandBodyMapper.ITEM_NAME_PROPERTY)); + } + +} diff --git a/alfa-service/src/main/java/de/ozgcloud/alfa/loeschanforderung/LoeschAnforderungHistorieProcessor.java b/alfa-service/src/main/java/de/ozgcloud/alfa/loeschanforderung/LoeschAnforderungHistorieProcessor.java new file mode 100644 index 0000000000000000000000000000000000000000..45ecd8907c4844361a93f6f33b031172d2834e95 --- /dev/null +++ b/alfa-service/src/main/java/de/ozgcloud/alfa/loeschanforderung/LoeschAnforderungHistorieProcessor.java @@ -0,0 +1,80 @@ +package de.ozgcloud.alfa.loeschanforderung; + +import java.util.HashSet; +import java.util.Set; +import java.util.stream.Stream; + +import org.apache.commons.collections.MapUtils; +import org.springframework.stereotype.Component; + +import de.ozgcloud.alfa.common.attacheditem.VorgangAttachedItem; +import de.ozgcloud.alfa.common.attacheditem.VorgangAttachedItemService; +import de.ozgcloud.alfa.common.command.Command; +import de.ozgcloud.alfa.common.command.CommandOrder; +import de.ozgcloud.alfa.common.command.CommandService; +import de.ozgcloud.alfa.common.command.CommandStatus; +import de.ozgcloud.alfa.historie.HistorieProcessor; +import lombok.RequiredArgsConstructor; + +@Component +@RequiredArgsConstructor +class LoeschAnforderungHistorieProcessor implements HistorieProcessor { + + private final CommandService commandService; + private final VorgangAttachedItemService vorgangAttachedItemService; + + @Override + public Stream<Command> process(Stream<Command> commands) { + var commandIdsToRemove = new HashSet<String>(); + var reducedCommands = commands.filter(this::isNotRevokedLoeschAnforderungZuruecknehmen) + .filter(this::isNotCreateLoeschAnforderungVorgangAttachedItem) + .map(command -> addLoeschAnforderungZuruecknehmenRelatedCommandIds(commandIdsToRemove, command)) + .toList(); + return reducedCommands.stream() + .filter(command -> !commandIdsToRemove.contains(command.getId())); + } + + boolean isNotRevokedLoeschAnforderungZuruecknehmen(Command command) { + if (!isLoeschAnforderungZuruecknehmen(command)) { + return true; + } + var changeStatusCommand = commandService.getById(getChangeStatusCommandId(command)); + return CommandStatus.REVOKED != changeStatusCommand.getStatus(); + } + + boolean isNotCreateLoeschAnforderungVorgangAttachedItem(Command command) { + if (!isCreateAttachedItem(command)) { + return true; + } + return !vorgangAttachedItemService.isLoeschAnforderung(MapUtils.getString(command.getBody(), VorgangAttachedItem.FIELD_ITEM_NAME)); + } + + private boolean isCreateAttachedItem(Command command) { + return CommandOrder.CREATE_ATTACHED_ITEM.equals(command.getCommandOrder()); + } + + Command addLoeschAnforderungZuruecknehmenRelatedCommandIds(Set<String> commandIdsToRemove, Command command) { + if (isLoeschAnforderungZuruecknehmen(command)) { + commandIdsToRemove.addAll(getCommandBodyIds(command)); + } + return command; + } + + private boolean isLoeschAnforderungZuruecknehmen(Command command) { + return CommandOrder.LOESCH_ANFORDERUNG_ZURUECKNEHMEN.equals(command.getCommandOrder()); + + } + + private Set<String> getCommandBodyIds(Command command) { + return Set.of(getDeleteAttachedItemCommandId(command), getChangeStatusCommandId(command)); + } + + private String getDeleteAttachedItemCommandId(Command command) { + return MapUtils.getString(command.getBody(), DeleteLoeschAnforderung.DELETE_ATTACHED_ITEM_COMMAND_ID_FIELD); + } + + String getChangeStatusCommandId(Command command) { + return MapUtils.getString(command.getBody(), DeleteLoeschAnforderung.CHANGE_STATUS_COMMAND_ID_FIELD); + } + +} diff --git a/alfa-service/src/main/java/de/ozgcloud/alfa/postfach/PostfachNachrichtHistorieProcessor.java b/alfa-service/src/main/java/de/ozgcloud/alfa/postfach/PostfachNachrichtHistorieProcessor.java new file mode 100644 index 0000000000000000000000000000000000000000..6af60c857ed773039bb1f5c86f2e29850e834a7d --- /dev/null +++ b/alfa-service/src/main/java/de/ozgcloud/alfa/postfach/PostfachNachrichtHistorieProcessor.java @@ -0,0 +1,78 @@ +package de.ozgcloud.alfa.postfach; + +import java.util.Map; +import java.util.stream.Stream; + +import org.apache.commons.collections.MapUtils; +import org.apache.commons.lang3.StringUtils; +import org.springframework.stereotype.Component; + +import de.ozgcloud.alfa.common.command.Command; +import de.ozgcloud.alfa.common.command.CommandBodyMapper; +import de.ozgcloud.alfa.common.command.CommandOrder; +import de.ozgcloud.alfa.historie.HistorieProcessor; + +@Component +class PostfachNachrichtHistorieProcessor implements HistorieProcessor { + + static final String DIRECTION_INCOMMING = "IN"; + static final String DIRECTION_OUTGOING = "OUT"; + static final String DIRECTION = "direction"; + static final String OZGCLOUD_NACHRICHTEN_MANAGER = "OzgCloud_NachrichtenManager"; + static final String CLIENT = "client"; + + @Override + public Stream<Command> process(Stream<Command> commands) { + return commands + .filter(this::isNotOutgoingPostfachNachrichtByNachrichtenManager) + .map(this::translateSendPostfachMailCommand) + .map(this::translateReceivePostfachNachrichtCommand); + } + + boolean isNotOutgoingPostfachNachrichtByNachrichtenManager(Command command) { + return !(isCreateAttachedItem(command) && isOzgCloudNachrichtenManager(command) && isOutgoing(command)); + } + + private boolean isOutgoing(Command command) { + return isDirection(command, DIRECTION_OUTGOING); + } + + public Command translateSendPostfachMailCommand(Command command) { + if (CommandOrder.SEND_POSTFACH_MAIL == command.getCommandOrder()) { + return command.toBuilder().order(CommandOrder.SEND_POSTFACH_NACHRICHT.name()).build(); + } + return command; + } + + public Command translateReceivePostfachNachrichtCommand(Command command) { + if (isIncomingNachrichtByNachrichtenManager(command)) { + return command.toBuilder().order(CommandOrder.RECEIVE_POSTFACH_NACHRICHT.name()).build(); + } + return command; + } + + boolean isIncomingNachrichtByNachrichtenManager(Command command) { + return isCreateAttachedItem(command) && isOzgCloudNachrichtenManager(command) && isIncomming(command); + } + + private boolean isCreateAttachedItem(Command command) { + return command.getCommandOrder().equals(CommandOrder.CREATE_ATTACHED_ITEM); + } + + private boolean isOzgCloudNachrichtenManager(Command command) { + return StringUtils.equals(MapUtils.getString(command.getBody(), CLIENT), OZGCLOUD_NACHRICHTEN_MANAGER); + } + + private boolean isIncomming(Command command) { + return isDirection(command, DIRECTION_INCOMMING); + } + + private boolean isDirection(Command command, String expectedDirection) { + return StringUtils.equals(MapUtils.getString(getItemMap(command), DIRECTION), expectedDirection); + } + + @SuppressWarnings("unchecked") + private Map<String, Object> getItemMap(Command command) { + return MapUtils.getMap(command.getBody(), CommandBodyMapper.ITEM_PROPERTY); + } +} diff --git a/alfa-service/src/main/java/de/ozgcloud/alfa/wiedervorlage/WiedervorlageHistorieProcessor.java b/alfa-service/src/main/java/de/ozgcloud/alfa/wiedervorlage/WiedervorlageHistorieProcessor.java new file mode 100644 index 0000000000000000000000000000000000000000..352b53f04707694244b3eef02d1062a70e8ad52c --- /dev/null +++ b/alfa-service/src/main/java/de/ozgcloud/alfa/wiedervorlage/WiedervorlageHistorieProcessor.java @@ -0,0 +1,88 @@ +package de.ozgcloud.alfa.wiedervorlage; + +import java.util.Map; +import java.util.Optional; +import java.util.stream.Stream; + +import org.apache.commons.collections.MapUtils; +import org.springframework.stereotype.Component; + +import de.ozgcloud.alfa.common.command.Command; +import de.ozgcloud.alfa.common.command.CommandBodyMapper; +import de.ozgcloud.alfa.common.command.CommandOrder; +import de.ozgcloud.alfa.common.command.LegacyOrder; +import de.ozgcloud.alfa.historie.HistorieProcessor; + +@Component +class WiedervorlageHistorieProcessor implements HistorieProcessor { + + @Override + public Stream<Command> process(Stream<Command> commands) { + return commands + .map(this::translateCreateAttachedItem) + .map(this::translateUpdateAttachedItem) + .map(this::translatePatchAttachedItem); + } + + Command translateCreateAttachedItem(Command command) { + if (isCreateWiederVorlage(command)) { + return command.toBuilder().order(LegacyOrder.CREATE_WIEDERVORLAGE).build(); + } + return command; + } + + private boolean isCreateWiederVorlage(Command command) { + return CommandOrder.CREATE_ATTACHED_ITEM == command.getCommandOrder() + && isWiedervorlageItem(command); + } + + Command translateUpdateAttachedItem(Command command) { + if (isEditWiedervorlage(command)) { + return command.toBuilder().order(LegacyOrder.EDIT_WIEDERVORLAGE).build(); + } + return command; + } + + private boolean isEditWiedervorlage(Command command) { + return CommandOrder.UPDATE_ATTACHED_ITEM == command.getCommandOrder() + && isWiedervorlageItem(command); + } + + Command translatePatchAttachedItem(Command command) { + if (isPatchWiedervorlage(command)) { + return translatePatchWiedervorlage(command); + } + return command; + } + + private boolean isPatchWiedervorlage(Command command) { + return CommandOrder.PATCH_ATTACHED_ITEM == command.getCommandOrder() && isWiedervorlageItem(command); + } + + private boolean isWiedervorlageItem(Command command) { + return getItemName(command).filter(name -> name.equals(Wiedervorlage.class.getSimpleName())).isPresent(); + } + + private Optional<String> getItemName(Command command) { + return Optional.ofNullable(MapUtils.getString(command.getBody(), CommandBodyMapper.ITEM_NAME_PROPERTY)); + } + + Command translatePatchWiedervorlage(Command command) { + return getDoneValue(command).map(isDone -> resolvePatchWiedervorlage(command, isDone)).orElse(command); + + } + + private Optional<Boolean> getDoneValue(Command command) { + return Optional.ofNullable(MapUtils.getBoolean(getItemMap(command), Wiedervorlage.DONE_FIELD)); + } + + @SuppressWarnings("unchecked") + private Map<String, Object> getItemMap(Command command) { + return MapUtils.getMap(command.getBody(), CommandBodyMapper.ITEM_PROPERTY); + } + + private Command resolvePatchWiedervorlage(Command command, Boolean isDone) { + return isDone.booleanValue() ? command.toBuilder().order(LegacyOrder.WIEDERVORLAGE_ERLEDIGEN).build() + : command.toBuilder().order(LegacyOrder.WIEDERVORLAGE_WIEDEREROEFFNEN).build(); + } +} diff --git a/alfa-service/src/test/java/de/ozgcloud/alfa/bescheid/BescheidHistorieProcessorTest.java b/alfa-service/src/test/java/de/ozgcloud/alfa/bescheid/BescheidHistorieProcessorTest.java index b6bf0944b34d9f7b1f9d93511ae3fe75bc2cd0cb..7867115f449b43e4f76270b7c92a7e12c1ab3b42 100644 --- a/alfa-service/src/test/java/de/ozgcloud/alfa/bescheid/BescheidHistorieProcessorTest.java +++ b/alfa-service/src/test/java/de/ozgcloud/alfa/bescheid/BescheidHistorieProcessorTest.java @@ -65,33 +65,39 @@ class BescheidHistorieProcessorTest { class TestProcess { private final Command command = CommandTestFactory.create(); - private final List<Command> commands = Collections.singletonList(command); + private final Stream<Command> commands = Stream.of(command); + private final Command relevantCommand = CommandTestFactory.create(); + private final Command filteredCommand = CommandTestFactory.create(); @BeforeEach void mock() { - doReturn(commands).when(processor).filterByOrder(commands); - doReturn(commands).when(processor).filterBescheidRelatedCommands(commands); + doReturn(Stream.of(relevantCommand)).when(processor).filterByOrder(any()); + doReturn(Stream.of(filteredCommand)).when(processor).filterBescheidRelatedCommands(any()); } @Test void shouldFilterByOrder() { - processor.process(commands); + process(); verify(processor).filterByOrder(commands); } @Test void shouldFilterBescheidRelatedCommands() { - processor.process(commands); + process(); - verify(processor).filterBescheidRelatedCommands(commands); + verify(processor).filterBescheidRelatedCommands(List.of(relevantCommand)); } @Test void shouldReturnCommands() { - var processedCommands = processor.process(commands); + var processedCommands = process(); - assertThat(processedCommands).containsExactly(command); + assertThat(processedCommands).containsExactly(filteredCommand); + } + + private Stream<Command> process() { + return processor.process(commands); } } @@ -104,7 +110,7 @@ class BescheidHistorieProcessorTest { void shouldFilterCommandWithOrder(CommandOrder order) { var command = CommandTestFactory.createBuilder().order(order.name()).build(); - var commands = processor.filterByOrder(Collections.singletonList(command)); + var commands = processor.filterByOrder(Stream.of(command)); assertThat(commands).isEmpty(); } @@ -114,7 +120,7 @@ class BescheidHistorieProcessorTest { void shouldKeepCommandWithOrder(CommandOrder order) { var command = CommandTestFactory.createBuilder().order(order.name()).build(); - var commands = processor.filterByOrder(Collections.singletonList(command)); + var commands = processor.filterByOrder(Stream.of(command)); assertThat(commands).containsExactly(command); } @@ -127,7 +133,7 @@ class BescheidHistorieProcessorTest { .body(Collections.singletonMap(VorgangAttachedItem.FIELD_ITEM_NAME, BescheidHistorieProcessor.BESCHEID_ITEM_NAME)) .build(); - var commands = processor.filterByOrder(Collections.singletonList(command)); + var commands = processor.filterByOrder(Stream.of(command)); assertThat(commands).isEmpty(); } diff --git a/alfa-service/src/test/java/de/ozgcloud/alfa/bescheid/DocumentHistorieProcessorTest.java b/alfa-service/src/test/java/de/ozgcloud/alfa/bescheid/DocumentHistorieProcessorTest.java index 41e1f2a11c72cfa85e948335a6b827b9b4a680d9..5df53b0da134933af263cf52da4ca005edae67e6 100644 --- a/alfa-service/src/test/java/de/ozgcloud/alfa/bescheid/DocumentHistorieProcessorTest.java +++ b/alfa-service/src/test/java/de/ozgcloud/alfa/bescheid/DocumentHistorieProcessorTest.java @@ -27,9 +27,8 @@ 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.Map; +import java.util.stream.Stream; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; @@ -55,11 +54,12 @@ class DocumentHistorieProcessorTest { class TestProcess { private final Command command = CommandTestFactory.create(); - private final List<Command> commands = Collections.singletonList(command); + private final Stream<Command> commands = Stream.of(command); + private final Command filteredCommand = CommandTestFactory.create(); @BeforeEach void mock() { - doReturn(commands).when(processor).filterIrrelevantCommands(any()); + doReturn(Stream.of(filteredCommand)).when(processor).filterIrrelevantCommands(any()); } @Test @@ -73,7 +73,7 @@ class DocumentHistorieProcessorTest { void shouldReturnCommands() { var processedCommands = processor.process(commands); - assertThat(processedCommands).containsExactly(command); + assertThat(processedCommands).containsExactly(filteredCommand); } } @@ -86,7 +86,7 @@ class DocumentHistorieProcessorTest { void shouldFilterCommandWithOrder(CommandOrder order) { var command = CommandTestFactory.createBuilder().order(order.toString()).build(); - var commands = processor.filterIrrelevantCommands(Collections.singletonList(command)); + var commands = processor.filterIrrelevantCommands(Stream.of(command)); assertThat(commands).isEmpty(); } @@ -96,7 +96,7 @@ class DocumentHistorieProcessorTest { void shouldKeepCommandWithOrder(CommandOrder order) { var command = CommandTestFactory.createBuilder().order(order.toString()).build(); - var commands = processor.filterIrrelevantCommands(Collections.singletonList(command)); + var commands = processor.filterIrrelevantCommands(Stream.of(command)); assertThat(commands).containsExactly(command); } @@ -108,7 +108,7 @@ class DocumentHistorieProcessorTest { .body(Map.of(VorgangAttachedItem.FIELD_ITEM_NAME, DocumentHistorieProcessor.DOCUMENT_ITEM_NAME)) .build(); - var commands = processor.filterIrrelevantCommands(Collections.singletonList(command)); + var commands = processor.filterIrrelevantCommands(Stream.of(command)); assertThat(commands).isEmpty(); } diff --git a/alfa-service/src/test/java/de/ozgcloud/alfa/common/attacheditem/VorgangAttachedItemHistorieProcessorTest.java b/alfa-service/src/test/java/de/ozgcloud/alfa/common/attacheditem/VorgangAttachedItemHistorieProcessorTest.java new file mode 100644 index 0000000000000000000000000000000000000000..f53d75a581b511b3cdc0f6775f24077e4bd35a58 --- /dev/null +++ b/alfa-service/src/test/java/de/ozgcloud/alfa/common/attacheditem/VorgangAttachedItemHistorieProcessorTest.java @@ -0,0 +1,44 @@ +package de.ozgcloud.alfa.common.attacheditem; + +import static org.assertj.core.api.Assertions.*; + +import java.util.stream.Stream; + +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.EnumSource; +import org.junit.jupiter.params.provider.EnumSource.Mode; +import org.mockito.Spy; + +import de.ozgcloud.alfa.common.command.CommandOrder; +import de.ozgcloud.alfa.common.command.CommandTestFactory; + +class VorgangAttachedItemHistorieProcessorTest { + + @Spy + private VorgangAttachedItemHistorieProcessor processor; + + @Nested + class TestProcess { + + @ParameterizedTest + @EnumSource(names = { "DELETE_ATTACHED_ITEM" }, mode = Mode.EXCLUDE) + void shouldKeepCommand(CommandOrder order) { + var command = CommandTestFactory.createBuilder().order(order.name()).build(); + + var commands = processor.process(Stream.of(command)); + + assertThat(commands).containsExactly(command); + } + + @ParameterizedTest + @EnumSource(names = { "DELETE_ATTACHED_ITEM" }, mode = Mode.INCLUDE) + void shouldRemoveCommand(CommandOrder order) { + var command = CommandTestFactory.createBuilder().order(order.name()).build(); + + var commands = processor.process(Stream.of(command)); + + assertThat(commands).isEmpty(); + } + } +} diff --git a/alfa-service/src/test/java/de/ozgcloud/alfa/historie/HistorieCommandHandlerTest.java b/alfa-service/src/test/java/de/ozgcloud/alfa/historie/HistorieCommandHandlerTest.java deleted file mode 100644 index 1ef92ad05e6ac8dba3008de06a9ba844004f4c98..0000000000000000000000000000000000000000 --- a/alfa-service/src/test/java/de/ozgcloud/alfa/historie/HistorieCommandHandlerTest.java +++ /dev/null @@ -1,335 +0,0 @@ -/* - * Copyright (C) 2023 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.alfa.historie; - -import static org.assertj.core.api.Assertions.*; -import static org.mockito.ArgumentMatchers.*; -import static org.mockito.Mockito.*; - -import java.util.Collections; -import java.util.Map; - -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.CsvSource; -import org.mockito.InjectMocks; -import org.mockito.Mock; -import org.mockito.Spy; - -import de.ozgcloud.alfa.common.attacheditem.VorgangAttachedItem; -import de.ozgcloud.alfa.common.attacheditem.VorgangAttachedItemService; -import de.ozgcloud.alfa.common.attacheditem.VorgangAttachedItemTestFactory; -import de.ozgcloud.alfa.common.command.Command; -import de.ozgcloud.alfa.common.command.CommandOrder; -import de.ozgcloud.alfa.common.command.CommandService; -import de.ozgcloud.alfa.common.command.CommandStatus; -import de.ozgcloud.alfa.common.command.CommandTestFactory; -import de.ozgcloud.alfa.common.command.LegacyOrder; -import de.ozgcloud.alfa.loeschanforderung.DeleteLoeschAnforderung; -import de.ozgcloud.alfa.postfach.PostfachMail; -import de.ozgcloud.alfa.wiedervorlage.Wiedervorlage; - -class HistorieCommandHandlerTest { - - @Spy - @InjectMocks - private HistorieCommandHandler handler; - - @Mock - private VorgangAttachedItemService vorgangAttachedItemService; - - @Mock - private CommandService commandService; - - @DisplayName("Is historie command") - @Nested - class TestIsHistorieCommand { - - @Test - void shouldReturnTrueIfNoItemNameExists() { - var result = handler - .isHistorieCommand(Command.builder().order(CommandOrder.CREATE_ATTACHED_ITEM.name()).body(Collections.emptyMap()).build()); - - assertThat(result).isTrue(); - } - - @Test - void shouldCallIsLoeschAnforderungZuruecknehmenRevoked() { - var command = CommandTestFactory.create(); - - handler.isHistorieCommand(command); - - verify(handler).isLoeschAnforderungZuruecknehmenRevoked(command); - } - - @Test - void shouldReturnFalseOnLoeschAnforderungZuruecknehmenRevoked() { - doReturn(true).when(handler).isLoeschAnforderungZuruecknehmenRevoked(any()); - - var result = handler.isHistorieCommand(CommandTestFactory.create()); - - assertThat(result).isFalse(); - } - - @Test - void shouldReturnFalseOnDeleteVorgangAttachedItem() { - var result = handler.isHistorieCommand(CommandTestFactory.createBuilder().order(CommandOrder.DELETE_ATTACHED_ITEM.name()).build()); - - assertThat(result).isFalse(); - } - - @Test - void shouldCallIsDeleteVorgangAttachedItem() { - var command = CommandTestFactory.create(); - - handler.isHistorieCommand(command); - - verify(handler).isDeleteVorgangAttachedItem(command); - } - } - - @DisplayName("postfach nachricht verification") - @Nested - class TestIsOutgoingPostfachNachrichtenByOzgCloudNachrichtenManager { - - private final Command matchingCommand = CommandTestFactory.createBuilder() - .order(CommandOrder.CREATE_ATTACHED_ITEM.name()) - .body(Map.of("item", Map.of(HistorieCommandHandler.DIRECTION, HistorieCommandHandler.DIRECTION_OUTGOING), - HistorieCommandHandler.CLIENT, HistorieCommandHandler.OZGCLOUD_NACHRICHTEN_MANAGER)) - .build(); - - @DisplayName("should return true if the command is CREATED_ATTACHED_ITEM order outgoing by mailserice") - @Test - void shouldReturnTrue() { - var result = handler.isOutgoingPostfachNachrichtByOzgCloudNachrichtenManager(matchingCommand); - - assertThat(result).isTrue(); - } - - @Test - void shouldReturnFalseOnIncoming() { - var nonMatchingCommand = matchingCommand.toBuilder() - .body(Map.of("item", Map.of(HistorieCommandHandler.DIRECTION, HistorieCommandHandler.DIRECTION_INCOMMING), - HistorieCommandHandler.CLIENT, HistorieCommandHandler.OZGCLOUD_NACHRICHTEN_MANAGER)) - .build(); - - var result = handler.isOutgoingPostfachNachrichtByOzgCloudNachrichtenManager(nonMatchingCommand); - - assertThat(result).isFalse(); - } - - @Test - void shouldReturnFalseOnOtherClient() { - var nonMatchingCommand = matchingCommand.toBuilder() - .body(Map.of("item", Map.of(HistorieCommandHandler.DIRECTION, HistorieCommandHandler.DIRECTION_OUTGOING), - HistorieCommandHandler.CLIENT, "Alfa")) - .build(); - - var result = handler.isOutgoingPostfachNachrichtByOzgCloudNachrichtenManager(nonMatchingCommand); - - assertThat(result).isFalse(); - } - } - - @Nested - class TestIsLoscheAnforderungVorgangAttachedItem { - - @Test - void shouldReturnFalse() { - when(vorgangAttachedItemService.isLoeschAnforderung(VorgangAttachedItemTestFactory.ITEM_NAME)).thenReturn(false); - - var result = handler.isCreateLoeschAnforderungVorgangAttachedItem(Command.builder().order(CommandOrder.CREATE_ATTACHED_ITEM.name()) - .body(Map.of( - VorgangAttachedItem.FIELD_ITEM_NAME, - VorgangAttachedItemTestFactory.ITEM_NAME)) - .build()); - - assertThat(result).isFalse(); - } - - @Test - void shouldReturnTrue() { - when(vorgangAttachedItemService.isLoeschAnforderung(VorgangAttachedItemTestFactory.ITEM_NAME)).thenReturn(true); - - var result = handler.isCreateLoeschAnforderungVorgangAttachedItem(Command.builder().order(CommandOrder.CREATE_ATTACHED_ITEM.name()) - .body(Map.of( - VorgangAttachedItem.FIELD_ITEM_NAME, - VorgangAttachedItemTestFactory.ITEM_NAME)) - .build()); - - assertThat(result).isTrue(); - } - } - - @DisplayName("Is loesch anforderung zuruecknehmen revoked") - @Nested - class TestIsLoeschAnforderungZuruecknehmenRevoked { - - @DisplayName("on matchin order") - @Nested - class TestOnMatchingOrder { - - private final Command loeschAnforderungZuruecknehmen = CommandTestFactory.createBuilder() - .order(CommandOrder.LOESCH_ANFORDERUNG_ZURUECKNEHMEN.name()) - .body(Map.of(DeleteLoeschAnforderung.CHANGE_STATUS_COMMAND_ID_FIELD, CommandTestFactory.ID)) - .build(); - - @Test - void shouldCallCommandService() { - when(commandService.getById(anyString())).thenReturn(CommandTestFactory.create()); - - handler.isLoeschAnforderungZuruecknehmenRevoked(loeschAnforderungZuruecknehmen); - - verify(commandService).getById(CommandTestFactory.ID); - } - - @Test - void shouldReturnTrueOnRevokedStatus() { - var revokedCommand = loeschAnforderungZuruecknehmen.toBuilder().status(CommandStatus.REVOKED).build(); - when(commandService.getById(anyString())).thenReturn(revokedCommand); - - var isRevoked = handler.isLoeschAnforderungZuruecknehmenRevoked(loeschAnforderungZuruecknehmen); - - assertThat(isRevoked).isTrue(); - } - - @Test - void shouldReturnFalseOnOtherStatus() { - var revokedCommand = loeschAnforderungZuruecknehmen.toBuilder().status(CommandStatus.FINISHED).build(); - when(commandService.getById(anyString())).thenReturn(revokedCommand); - - var isRevoked = handler.isLoeschAnforderungZuruecknehmenRevoked(loeschAnforderungZuruecknehmen); - - assertThat(isRevoked).isFalse(); - } - } - - @Test - void shouldReturnFalseOnNonMatchingOrder() { - var isRevoked = handler.isLoeschAnforderungZuruecknehmenRevoked(CommandTestFactory.create()); - - assertThat(isRevoked).isFalse(); - } - } - - @DisplayName("translate order") - @Nested - class TestTranslateOrders { - - @ParameterizedTest - @CsvSource(value = { "CREATE_KOMMENTAR;Kommentar", "CREATE_WIEDERVORLAGE;Wiedervorlage" }, delimiter = ';') - void shouldTranslateToCreateOrder(String target, String itemName) { - var command = handler.translateOrder(createCommand(itemName, CommandOrder.CREATE_ATTACHED_ITEM)); - - assertThat(command.getOrder()).isEqualTo(target); - } - - @ParameterizedTest - @CsvSource(value = { "EDIT_KOMMENTAR;Kommentar", "EDIT_WIEDERVORLAGE;Wiedervorlage" }, delimiter = ';') - void shouldTranslateToEditOrder(String target, String itemName) { - var command = handler.translateOrder(createCommand(itemName, CommandOrder.UPDATE_ATTACHED_ITEM)); - - assertThat(command.getOrder()).isEqualTo(target); - } - - @ParameterizedTest - @CsvSource(value = { "WIEDERVORLAGE_ERLEDIGEN;true", "WIEDERVORLAGE_WIEDEREROEFFNEN;false" }, delimiter = ';') - void shouldTranslateToWiedervolageErledigenOrWiedervolageWiedereroeffnen(String target, String doneValue) { - var command = handler.translateOrder( - createCommand(Wiedervorlage.class.getSimpleName(), CommandOrder.PATCH_ATTACHED_ITEM, Boolean.valueOf(doneValue))); - - assertThat(command.getOrder()).isEqualTo(target); - } - - @ParameterizedTest - @CsvSource(value = { "RECEIVE_POSTFACH_NACHRICHT;IN" }, delimiter = ';') - void shouldTranslateToReveivedIncomminNachricht(String target, String direction) { - var command = handler.translateOrder( - createCommand("OzgCloud_NachrichtenManager", CommandOrder.CREATE_ATTACHED_ITEM, direction)); - - assertThat(command.getOrder()).isEqualTo(target); - } - - @Test - void shouldHandleMissingDone() { - var command = handler.translateOrder(createCommand(Wiedervorlage.class.getSimpleName(), CommandOrder.PATCH_ATTACHED_ITEM)); - - assertThat(command.getCommandOrder()).isEqualTo(CommandOrder.PATCH_ATTACHED_ITEM); - } - - @Test - void shouldHandleUnkownOrder() { - var command = handler - .translateOrder(createCommand(Wiedervorlage.class.getSimpleName(), CommandOrder.VORGANG_ABSCHLIESSEN)); - - assertThat(command.getCommandOrder()).isEqualTo(CommandOrder.VORGANG_ABSCHLIESSEN); - } - - @Test - void shouldHandleMissingItemName() { - var command = CommandTestFactory.createBuilder().order(LegacyOrder.EDIT_KOMMENTAR).body(Map.of("item", Map.of("value", "test"))) - .build(); - - var translatedCommand = handler.translateOrder(command); - - assertThat(translatedCommand.getOrder()).isEqualTo(LegacyOrder.EDIT_KOMMENTAR); - } - - private Command createCommand(String itemName, CommandOrder order) { - return CommandTestFactory.createBuilder().order(order.name()) - .body(Map.of(VorgangAttachedItem.FIELD_ITEM_NAME, itemName, "item", Map.of("value", "test"))).build(); - } - - private Command createCommand(String itemName, CommandOrder order, boolean done) { - return CommandTestFactory.createBuilder().order(order.name()) - .body(Map.of(VorgangAttachedItem.FIELD_ITEM_NAME, itemName, "item", Map.of("done", done))) - .build(); - } - - private Command createCommand(String client, CommandOrder order, String direction) { - return CommandTestFactory.createBuilder().order(order.name()) - .body(Map.of(HistorieCommandHandler.CLIENT, client, VorgangAttachedItem.FIELD_ITEM_NAME, PostfachMail.class.getSimpleName(), - "item", - Map.of(HistorieCommandHandler.DIRECTION, direction))) - .build(); - } - - } - - @DisplayName("SEND_POSTFACH_MAIL") - @Nested - class TestSendPostfachMail { - - private Command command = CommandTestFactory.createBuilder().order(CommandOrder.SEND_POSTFACH_MAIL.name()).build(); - - @Test - void shouldHandleUnkownOrder() { - var translatedCommand = handler.translateOrder(command); - - assertThat(translatedCommand.getCommandOrder()).isEqualTo(CommandOrder.SEND_POSTFACH_NACHRICHT); - } - } -} \ No newline at end of file diff --git a/alfa-service/src/test/java/de/ozgcloud/alfa/historie/HistorieServiceTest.java b/alfa-service/src/test/java/de/ozgcloud/alfa/historie/HistorieServiceTest.java index 6d6a75467c7bc45f9aaf65191a5e0dc9ceacce05..725768dcbcf608b24d78caccb7397a6eb5d4788b 100644 --- a/alfa-service/src/test/java/de/ozgcloud/alfa/historie/HistorieServiceTest.java +++ b/alfa-service/src/test/java/de/ozgcloud/alfa/historie/HistorieServiceTest.java @@ -28,26 +28,19 @@ import static org.mockito.ArgumentMatchers.*; import static org.mockito.Mockito.*; import java.util.ArrayList; -import java.util.Collections; import java.util.List; -import java.util.Map; -import java.util.UUID; +import java.util.stream.Stream; import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; -import org.mockito.ArgumentCaptor; -import org.mockito.Captor; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.Spy; import de.ozgcloud.alfa.common.command.Command; -import de.ozgcloud.alfa.common.command.CommandOrder; import de.ozgcloud.alfa.common.command.CommandService; import de.ozgcloud.alfa.common.command.CommandTestFactory; -import de.ozgcloud.alfa.loeschanforderung.DeleteLoeschAnforderung; import de.ozgcloud.alfa.vorgang.VorgangHeaderTestFactory; class HistorieServiceTest { @@ -57,111 +50,85 @@ class HistorieServiceTest { private HistorieService service; @Mock private CommandService commandService; - @Mock - private HistorieCommandHandler historieCommandHandler; @Spy private List<HistorieProcessor> processors = new ArrayList<>(); @Mock - private HistorieProcessor processor; + private HistorieProcessor firstProcessor; + @Mock + private HistorieProcessor secondProcessor; - @DisplayName("Find finished commands") @Nested class TestFindFinishedCommands { + private final Stream<Command> commands = Stream.of(CommandTestFactory.create()); + @BeforeEach - void mockProcessor() { - processors.add(processor); + void setUpMock() { + when(commandService.findFinishedCommands(any())).thenReturn(commands); } - @DisplayName("process flow") - @Nested - class TestProcessFlow { - - private Command responseCommand = CommandTestFactory.create(); + @Test + void shouldCallCommandServiceForFinishedCommands() { + findFinishedCommands(); - @Captor - private ArgumentCaptor<List<Command>> commandCaptor; + verify(commandService).findFinishedCommands(VorgangHeaderTestFactory.ID); + } - @BeforeEach - void initMock() { - when(commandService.findFinishedCommands(any())).thenReturn(List.of(responseCommand).stream()); - when(historieCommandHandler.isHistorieCommand(any())).thenReturn(true); - when(historieCommandHandler.translateOrder(any())).thenAnswer(i -> i.getArgument(0)); + @Test + void shouldCallProcessCommands() { + findFinishedCommands(); - } + verify(service).processCommands(commands); + } - @Test - void shouldCallService() { - service.findFinishedCommands(CommandTestFactory.VORGANG_ID).toList(); + @Test + void shouldReturnProcessedCommands() { + var processedCommands = Stream.of(CommandTestFactory.create()); + doReturn(processedCommands).when(service).processCommands(commands); - verify(commandService).findFinishedCommands(VorgangHeaderTestFactory.ID); - } + var finishedCommands = findFinishedCommands(); - @Test - void shouldFilterInvalidCommands() { - service.findFinishedCommands(CommandTestFactory.VORGANG_ID).toList(); + assertThat(finishedCommands).isSameAs(processedCommands); + } - verify(historieCommandHandler).isHistorieCommand(responseCommand); - } + private Stream<Command> findFinishedCommands() { + return service.findFinishedCommands(VorgangHeaderTestFactory.ID); + } + } - @Test - void shouldTranslateCommandOrderByCommandHandler() { - service.findFinishedCommands(CommandTestFactory.VORGANG_ID).toList(); + @Nested + class TestProcessCommands { - verify(historieCommandHandler).translateOrder(responseCommand); - } + private final Stream<Command> inputCommands = Stream.of(CommandTestFactory.create()); + private final Stream<Command> processedOnceCommands = Stream.of(CommandTestFactory.create()); + private final Stream<Command> processedTwiceCommands = Stream.of(CommandTestFactory.create()); - @Test - void shouldProcessCommands() { - service.findFinishedCommands(CommandTestFactory.VORGANG_ID).toList(); + @BeforeEach + void setProcessorMocks() { + processors.addAll(List.of(firstProcessor, secondProcessor)); + when(firstProcessor.process(any())).thenReturn(processedOnceCommands); + when(secondProcessor.process(any())).thenReturn(processedTwiceCommands); + } - verify(processor).process(commandCaptor.capture()); - assertThat(commandCaptor.getValue()).containsExactly(responseCommand); - } + @Test + void shouldProcessCommands() { + service.processCommands(inputCommands); - @Test - void shouldReturnProcessedCommands() { - var processedCommands = Collections.singletonList(CommandTestFactory.create()); - when(processor.process(any())).thenReturn(processedCommands); + verify(firstProcessor).process(inputCommands); + } - var commands = service.findFinishedCommands(CommandTestFactory.VORGANG_ID).toList(); + @Test + void shouldDoSubsequentProcessing() { + service.processCommands(inputCommands); - assertThat(commands).isEqualTo(processedCommands); - } + verify(secondProcessor).process(processedOnceCommands); } - @DisplayName("Filter deleteLoeschAnforderung body commands") - @Nested - class TestFilterDeleteLoeschAnforderungBodyCommands { - - private final String deleteAttachedItemCommandId = UUID.randomUUID().toString(); - private final String changeStatusCommandId = UUID.randomUUID().toString(); - private final Map<String, Object> bodyMap = Map.of(DeleteLoeschAnforderung.DELETE_ATTACHED_ITEM_COMMAND_ID_FIELD, - deleteAttachedItemCommandId, - DeleteLoeschAnforderung.CHANGE_STATUS_COMMAND_ID_FIELD, changeStatusCommandId); - private final Command deleteLoeschAnforderungCommand = CommandTestFactory.createBuilder() - .order(CommandOrder.LOESCH_ANFORDERUNG_ZURUECKNEHMEN.name()) - .body(bodyMap).build(); - private final Command deleteAttachedItemCommand = CommandTestFactory.createBuilder().id(deleteAttachedItemCommandId).build(); - private final Command changeStatusCommandICommand = CommandTestFactory.createBuilder().id(changeStatusCommandId).build(); - - private final List<Command> finishedCommands = List.of(deleteLoeschAnforderungCommand, deleteAttachedItemCommand, - changeStatusCommandICommand); - - @BeforeEach - void mock() { - when(historieCommandHandler.isHistorieCommand(any())).thenReturn(true); - when(commandService.findFinishedCommands(any())).thenReturn(finishedCommands.stream()); - when(historieCommandHandler.translateOrder(any())).thenAnswer(i -> i.getArgument(0)); - when(processor.process(any())).thenAnswer(i -> i.getArgument(0)); - } - - @Test - void shouldFilterCommandsRelatedInBody() { - var commands = service.findFinishedCommands(CommandTestFactory.VORGANG_ID).toList(); - - assertThat(commands).hasSize(1).containsExactly(deleteLoeschAnforderungCommand); - } + @Test + void shouldReturnCommandsAfterProcessing() { + var resultCommands = service.processCommands(inputCommands); + + assertThat(resultCommands).isEqualTo(processedTwiceCommands); } } } \ No newline at end of file diff --git a/alfa-service/src/test/java/de/ozgcloud/alfa/kommentar/KommentarHistorieProcessorTest.java b/alfa-service/src/test/java/de/ozgcloud/alfa/kommentar/KommentarHistorieProcessorTest.java new file mode 100644 index 0000000000000000000000000000000000000000..c67a8dfc3b86ab32f37c7d889eafb62cb3787ec0 --- /dev/null +++ b/alfa-service/src/test/java/de/ozgcloud/alfa/kommentar/KommentarHistorieProcessorTest.java @@ -0,0 +1,176 @@ +package de.ozgcloud.alfa.kommentar; + +import static org.assertj.core.api.Assertions.*; +import static org.mockito.Mockito.*; + +import java.util.List; +import java.util.Map; +import java.util.stream.Stream; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.mockito.Spy; + +import com.thedeanda.lorem.LoremIpsum; + +import de.ozgcloud.alfa.common.command.Command; +import de.ozgcloud.alfa.common.command.CommandBodyMapper; +import de.ozgcloud.alfa.common.command.CommandOrder; +import de.ozgcloud.alfa.common.command.CommandTestFactory; +import de.ozgcloud.alfa.common.command.LegacyOrder; + +class KommentarHistorieProcessorTest { + + @Spy + private KommentarHistorieProcessor processor; + + @Nested + class TestProcess { + + private final Command command = CommandTestFactory.create(); + private final Command translatedOnceCommand = CommandTestFactory.create(); + private final Command translatedTwiceCommand = CommandTestFactory.create(); + + @BeforeEach + void mockTranslation() { + doReturn(translatedOnceCommand).when(processor).translateCreateKommentar(command); + doReturn(translatedTwiceCommand).when(processor).translateEditKommentar(translatedOnceCommand); + } + + @Test + void shouldCallTranslateCreateKommentar() { + process(); + + verify(processor).translateCreateKommentar(command); + } + + @Test + void shouldCallTranslateEditKommentar() { + process(); + + verify(processor).translateEditKommentar(translatedOnceCommand); + } + + @Test + void shouldReturnStreamOfTranslatedCommand() { + var commands = process(); + + assertThat(commands).containsExactly(translatedTwiceCommand); + } + + private List<Command> process() { + return processor.process(Stream.of(command)).toList(); + } + } + + @Nested + class TestTranslateCreateKommentar { + + @Nested + class TestOnNotCreateAttachedItem { + + @Test + void shouldReturnSameCommand() { + var command = CommandTestFactory.create(); + + var resultCommand = processor.translateCreateKommentar(command); + + assertThat(resultCommand).isSameAs(command); + } + } + + @Nested + class TestOnCreateAttachedItem { + + private Command.CommandBuilder commandBuilder = CommandTestFactory.createBuilder() + .order(CommandOrder.CREATE_ATTACHED_ITEM.name()); + + @Nested + class TestOnIsCreateKommentar { + @Test + void shouldTranslateToCreateKommentar() { + var commandBody = Map.of(CommandBodyMapper.ITEM_NAME_PROPERTY, Kommentar.class.getSimpleName()); + var command = commandBuilder.body(commandBody).build(); + var expectedCommand = CommandTestFactory.createBuilder() + .order(LegacyOrder.CREATE_KOMMENTAR) + .body(commandBody) + .build(); + + var resultCommand = processor.translateCreateKommentar(command); + + assertThat(resultCommand).usingRecursiveComparison().isEqualTo(expectedCommand); + } + } + + @Nested + class TestOnIsNotCreateKommentar { + + @Test + void shouldReturnSameCommand() { + var commandBody = Map.of(CommandBodyMapper.ITEM_NAME_PROPERTY, LoremIpsum.getInstance().getWords(1)); + var command = commandBuilder.body(commandBody).build(); + + var resultCommand = processor.translateCreateKommentar(command); + + assertThat(resultCommand).isSameAs(command); + } + } + } + } + + @Nested + class TestTranslateEditKommentar { + + @Nested + class TestOnNotUpdateAttachedItem { + + @Test + void shouldReturnSameCommand() { + var command = CommandTestFactory.create(); + + var resultCommand = processor.translateEditKommentar(command); + + assertThat(resultCommand).isSameAs(command); + } + } + + @Nested + class TestOnUpdateAttachedItem { + + private Command.CommandBuilder commandBuilder = CommandTestFactory.createBuilder() + .order(CommandOrder.UPDATE_ATTACHED_ITEM.name()); + + @Nested + class TestOnIsEditKommentar { + @Test + void shouldTranslateToCreateKommentar() { + var commandBody = Map.of(CommandBodyMapper.ITEM_NAME_PROPERTY, Kommentar.class.getSimpleName()); + var command = commandBuilder.body(commandBody).build(); + var expectedCommand = CommandTestFactory.createBuilder() + .order(LegacyOrder.EDIT_KOMMENTAR) + .body(commandBody) + .build(); + + var resultCommand = processor.translateEditKommentar(command); + + assertThat(resultCommand).usingRecursiveComparison().isEqualTo(expectedCommand); + } + } + + @Nested + class TestOnIsNotEditKommentar { + + @Test + void shouldReturnSameCommand() { + var commandBody = Map.of(CommandBodyMapper.ITEM_NAME_PROPERTY, LoremIpsum.getInstance().getWords(1)); + var command = commandBuilder.body(commandBody).build(); + + var resultCommand = processor.translateEditKommentar(command); + + assertThat(resultCommand).isSameAs(command); + } + } + } + } +} diff --git a/alfa-service/src/test/java/de/ozgcloud/alfa/loeschanforderung/LoeschAnforderungHistorieProcessorTest.java b/alfa-service/src/test/java/de/ozgcloud/alfa/loeschanforderung/LoeschAnforderungHistorieProcessorTest.java new file mode 100644 index 0000000000000000000000000000000000000000..17ec36a7d571aa97572f9093ab8d8c4fdd835dde --- /dev/null +++ b/alfa-service/src/test/java/de/ozgcloud/alfa/loeschanforderung/LoeschAnforderungHistorieProcessorTest.java @@ -0,0 +1,346 @@ +package de.ozgcloud.alfa.loeschanforderung; + +import static org.assertj.core.api.Assertions.*; +import static org.mockito.ArgumentMatchers.*; +import static org.mockito.Mockito.*; + +import java.util.Collection; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; +import java.util.UUID; +import java.util.stream.Stream; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.EnumSource; +import org.junit.jupiter.params.provider.ValueSource; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.Spy; +import org.mockito.invocation.InvocationOnMock; + +import com.thedeanda.lorem.LoremIpsum; + +import de.ozgcloud.alfa.common.attacheditem.VorgangAttachedItem; +import de.ozgcloud.alfa.common.attacheditem.VorgangAttachedItemService; +import de.ozgcloud.alfa.common.command.Command; +import de.ozgcloud.alfa.common.command.CommandOrder; +import de.ozgcloud.alfa.common.command.CommandService; +import de.ozgcloud.alfa.common.command.CommandStatus; +import de.ozgcloud.alfa.common.command.CommandTestFactory; + +class LoeschAnforderungHistorieProcessorTest { + + @Spy + @InjectMocks + private LoeschAnforderungHistorieProcessor processor; + + @Mock + private CommandService commandService; + @Mock + private VorgangAttachedItemService vorgangAttachedItemService; + + @Nested + class TestProcess { + + private final Command command = CommandTestFactory.create(); + + @Test + void shouldCallIsNotRevokedLoeschAnforderungZuruecknehmen() { + process(); + + verify(processor).isNotRevokedLoeschAnforderungZuruecknehmen(command); + } + + @Nested + class TestOnIsNotRevokedLoeschAnforderungZuruecknehmen { + + @BeforeEach + void mock() { + doReturn(true).when(processor).isNotRevokedLoeschAnforderungZuruecknehmen(any()); + } + + @Test + void shouldCallIsNotCreateLoeschAnforderungVorgangAttachedItem() { + process(); + + verify(processor).isNotCreateLoeschAnforderungVorgangAttachedItem(command); + } + + @Nested + class TestOnIsNotCreateLoeschAnforderungVorgangAttachedItem { + @BeforeEach + void mock() { + doReturn(true).when(processor).isNotCreateLoeschAnforderungVorgangAttachedItem(any()); + } + + @Test + void shouldAddLoeschAnforderungZuruecknehmenRelatedCommandIds() { + process(); + + verify(processor).addLoeschAnforderungZuruecknehmenRelatedCommandIds(argThat(Collection::isEmpty), eq(command)); + } + + @Test + void shouldRemoveLoeschAnforderungZuruecknehmenRelatedCommands() { + doAnswer(this::addCommandIdToSet).when(processor) + .addLoeschAnforderungZuruecknehmenRelatedCommandIds(anySet(), any()); + + var commands = process(); + + assertThat(commands).isEmpty(); + } + + @SuppressWarnings("unchecked") + private Object addCommandIdToSet(InvocationOnMock invokation) { + invokation.getArgument(0, Set.class).add(CommandTestFactory.ID); + return command; + } + + @Test + void shouldKeepCommandsWithDifferentId() { + doAnswer(this::addDummyIdToSet).when(processor) + .addLoeschAnforderungZuruecknehmenRelatedCommandIds(anySet(), any()); + + var commands = process(); + + assertThat(commands).containsExactly(command); + } + + @SuppressWarnings("unchecked") + private Object addDummyIdToSet(InvocationOnMock invokation) { + invokation.getArgument(0, Set.class).add("dummy"); + return command; + } + } + + @Nested + class TestOnIsCreateLoeschAnforderungVorgangAttachedItem { + @BeforeEach + void mock() { + doReturn(false).when(processor).isNotCreateLoeschAnforderungVorgangAttachedItem(any()); + } + + @Test + void shouldNotCallAddLoeschAnforderungZuruecknehmenRelatedCommandIds() { + process(); + + verify(processor, never()).addLoeschAnforderungZuruecknehmenRelatedCommandIds(any(), any()); + } + + @Test + void shouldRemoveCommand() { + var commands = process(); + + assertThat(commands).isEmpty(); + } + } + } + + @Nested + class TestOnIsRevokedLoeschAnforderungZuruecknehmen { + + @BeforeEach + void mock() { + doReturn(false).when(processor).isNotRevokedLoeschAnforderungZuruecknehmen(any()); + } + + @Test + void shouldNotGetLoeschAnforderungZuruecknehmenRelatedCommandIds() { + process(); + + verify(processor, never()).addLoeschAnforderungZuruecknehmenRelatedCommandIds(anySet(), any()); + } + + @Test + void shouldRemoveRevokedLoeschAnforderungenZuruecknehmen() { + var commands = process(); + + assertThat(commands).isEmpty(); + } + } + + private Stream<Command> process() { + return processor.process(Stream.of(command)); + } + + } + + @Nested + class TestIsNotRevokedLoeschAnforderungZuruecknehmen { + + @Nested + class TestOnIsNotLoeschAnforderungZurücknehmen { + + private final Command command = CommandTestFactory.create(); + + @Test + void shouldReturnTrue() { + var result = processor.isNotRevokedLoeschAnforderungZuruecknehmen(command); + + assertThat(result).isTrue(); + } + } + + @Nested + class TestOnIsLoeschAnforderungZurücknehmen { + + private final Command command = CommandTestFactory.createBuilder() + .order(CommandOrder.LOESCH_ANFORDERUNG_ZURUECKNEHMEN.toString()) + .build(); + + private final String changeStatusCommandId = UUID.randomUUID().toString(); + + @BeforeEach + void mock() { + doReturn(changeStatusCommandId).when(processor).getChangeStatusCommandId(any()); + when(commandService.getById(any())).thenReturn(CommandTestFactory.create()); + } + + @Test + void shouldGetChangeStatusCommandId() { + isNotRevokedLoeschAnforderungZuruecknehmen(); + + verify(processor).getChangeStatusCommandId(command); + } + + @Test + void shouldGetChangeStatusCommand() { + isNotRevokedLoeschAnforderungZuruecknehmen(); + + verify(commandService).getById(changeStatusCommandId); + } + + @Test + void shouldReturnTrueIfChangeStatusCommandIsNotRevoked() { + var changeStatusCommand = CommandTestFactory.createBuilder().status(CommandStatus.FINISHED).build(); + when(commandService.getById(any())).thenReturn(changeStatusCommand); + + var result = isNotRevokedLoeschAnforderungZuruecknehmen(); + + assertThat(result).isTrue(); + } + + @Test + void shouldReturnFalseIfChangeStatusCommandIsRevoked() { + var changeStatusCommand = CommandTestFactory.createBuilder().status(CommandStatus.REVOKED).build(); + when(commandService.getById(any())).thenReturn(changeStatusCommand); + + var result = isNotRevokedLoeschAnforderungZuruecknehmen(); + + assertThat(result).isFalse(); + } + + private boolean isNotRevokedLoeschAnforderungZuruecknehmen() { + return processor.isNotRevokedLoeschAnforderungZuruecknehmen(command); + } + } + } + + @Nested + class TestIsNotCreateLoeschAnforderungVorgangAttachedItem { + + @ParameterizedTest + @EnumSource(names = { "CREATE_ATTACHED_ITEM" }, mode = EnumSource.Mode.EXCLUDE) + void shouldReturnTrueForNotCreateAttachedItem(CommandOrder order) { + var command = CommandTestFactory.createBuilder().order(order.name()).build(); + + var result = processor.isNotCreateLoeschAnforderungVorgangAttachedItem(command); + + assertThat(result).isTrue(); + } + + @ParameterizedTest + @EnumSource(names = { "CREATE_ATTACHED_ITEM" }, mode = EnumSource.Mode.EXCLUDE) + void shouldNotCallVorgangAttachedItemService(CommandOrder order) { + var command = CommandTestFactory.createBuilder().order(order.name()).build(); + + processor.isNotCreateLoeschAnforderungVorgangAttachedItem(command); + + verify(vorgangAttachedItemService, never()).isLoeschAnforderung(any()); + } + + @Nested + class TestOnCreateAttacheditemOrder { + + private final String itemName = LoremIpsum.getInstance().getWords(1); + private final Map<String, ?> commandBody = Map.of(VorgangAttachedItem.FIELD_ITEM_NAME, itemName); + private final Command command = CommandTestFactory.createBuilder() + .order(CommandOrder.CREATE_ATTACHED_ITEM.name()) + .body(commandBody) + .build(); + + @Test + void shouldCallVorgangAttachedItemService() { + processor.isNotCreateLoeschAnforderungVorgangAttachedItem(command); + + verify(vorgangAttachedItemService).isLoeschAnforderung(itemName); + } + + @ParameterizedTest + @ValueSource(booleans = { true, false }) + void shouldReturnNegatedResult(boolean isLoeschAnforderung) { + when(vorgangAttachedItemService.isLoeschAnforderung(any())).thenReturn(isLoeschAnforderung); + + var result = processor.isNotCreateLoeschAnforderungVorgangAttachedItem(command); + + assertThat(result).isNotEqualTo(isLoeschAnforderung); + } + } + } + + @Nested + class TestGetChangeStatusCommandId { + + @Test + void shouldReturnChangeStatusCommandId() { + var changeStatusCommandId = UUID.randomUUID().toString(); + var commandBody = Map.of(DeleteLoeschAnforderung.CHANGE_STATUS_COMMAND_ID_FIELD, changeStatusCommandId); + var command = CommandTestFactory.createBuilder().body(commandBody).build(); + + var id = processor.getChangeStatusCommandId(command); + + assertThat(id).isEqualTo(changeStatusCommandId); + } + } + + @Nested + class TestAddLoeschAnforderungZuruecknehmenRelatedCommandIds { + private final String changeStatusCommandId = UUID.randomUUID().toString(); + private final String deleteAttachedItemCommandId = UUID.randomUUID().toString(); + private final Map<String, ?> commandBody = Map.of( + DeleteLoeschAnforderung.CHANGE_STATUS_COMMAND_ID_FIELD, changeStatusCommandId, + DeleteLoeschAnforderung.DELETE_ATTACHED_ITEM_COMMAND_ID_FIELD, deleteAttachedItemCommandId, + LoremIpsum.getInstance().getWords(1), UUID.randomUUID().toString()); + private final Command command = CommandTestFactory.createBuilder() + .order(CommandOrder.LOESCH_ANFORDERUNG_ZURUECKNEHMEN.name()) + .body(commandBody) + .build(); + private final HashSet<String> idsToRemove = new HashSet<>(); + + @Test + void shouldReturnSameCommand() { + var returnedCommand = processor.addLoeschAnforderungZuruecknehmenRelatedCommandIds(idsToRemove, command); + + assertThat(returnedCommand).isSameAs(command); + } + + @Test + void shouldNotAddAnyIds() { + processor.addLoeschAnforderungZuruecknehmenRelatedCommandIds(idsToRemove, CommandTestFactory.create()); + + assertThat(idsToRemove).isEmpty(); + } + + @Test + void shouldAddRelatedCommandIdsOfLoeschAnforderungenZuruecknehmen() { + processor.addLoeschAnforderungZuruecknehmenRelatedCommandIds(idsToRemove, command); + + assertThat(idsToRemove).containsExactlyInAnyOrder(changeStatusCommandId, deleteAttachedItemCommandId); + } + } + +} diff --git a/alfa-service/src/test/java/de/ozgcloud/alfa/postfach/PostfachNachrichtHistorieProcessorTest.java b/alfa-service/src/test/java/de/ozgcloud/alfa/postfach/PostfachNachrichtHistorieProcessorTest.java new file mode 100644 index 0000000000000000000000000000000000000000..300249da5973529dc8243ec16debb14e007a03a4 --- /dev/null +++ b/alfa-service/src/test/java/de/ozgcloud/alfa/postfach/PostfachNachrichtHistorieProcessorTest.java @@ -0,0 +1,274 @@ +package de.ozgcloud.alfa.postfach; + +import static org.assertj.core.api.Assertions.*; +import static org.mockito.ArgumentMatchers.*; +import static org.mockito.Mockito.*; + +import java.util.List; +import java.util.Map; +import java.util.stream.Stream; + +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.mockito.Spy; + +import com.thedeanda.lorem.LoremIpsum; + +import de.ozgcloud.alfa.common.command.Command; +import de.ozgcloud.alfa.common.command.CommandOrder; +import de.ozgcloud.alfa.common.command.CommandTestFactory; + +class PostfachNachrichtHistorieProcessorTest { + + @Spy + private PostfachNachrichtHistorieProcessor processor; + + @Nested + class TestProcess { + + private final Command command = CommandTestFactory.create(); + + @Test + void shouldCallIsNotOutgoingPostfachNachrichtByNachrichtenManager() { + process(); + + verify(processor).isNotOutgoingPostfachNachrichtByNachrichtenManager(command); + } + + @Test + void shouldContainCommandIfIsNotOutgoingPostfachNachrichtByNachrichtenManager() { + doReturn(true).when(processor).isNotOutgoingPostfachNachrichtByNachrichtenManager(any()); + doReturn(command).when(processor).translateSendPostfachMailCommand(command); + doReturn(command).when(processor).translateReceivePostfachNachrichtCommand(command); + + var commands = process(); + + assertThat(commands).containsExactly(command); + } + + @Test + void shouldNotContainCommandIfisNotOutgoingPostfachNachrichtByNachrichtenManager() { + doReturn(false).when(processor).isNotOutgoingPostfachNachrichtByNachrichtenManager(any()); + + var commands = process(); + + assertThat(commands).isEmpty(); + } + + @Test + void shouldTranslateSendPostfachMailCommand() { + doReturn(true).when(processor).isNotOutgoingPostfachNachrichtByNachrichtenManager(any()); + + process(); + + verify(processor).translateSendPostfachMailCommand(command); + } + + @Test + void shouldReturnTranslatedSendPostfachMailCommand() { + var translatedCommandOrder = CommandTestFactory.create(); + doReturn(true).when(processor).isNotOutgoingPostfachNachrichtByNachrichtenManager(any()); + doReturn(translatedCommandOrder).when(processor).translateSendPostfachMailCommand(command); + doAnswer(invocation -> invocation.getArgument(0)).when(processor).translateReceivePostfachNachrichtCommand(any()); + + var commands = process(); + + assertThat(commands).containsExactly(translatedCommandOrder); + } + + @Test + void shouldTranslateReceivePostfachNachrichtCommand() { + doReturn(true).when(processor).isNotOutgoingPostfachNachrichtByNachrichtenManager(any()); + doAnswer(invocation -> invocation.getArgument(0)).when(processor).translateSendPostfachMailCommand(any()); + + process(); + + verify(processor).translateReceivePostfachNachrichtCommand(command); + } + + @Test + void shouldReturnTranslatedReceivePostfachNachrichtCommand() { + var translatedCommandOrder = CommandTestFactory.create(); + doReturn(true).when(processor).isNotOutgoingPostfachNachrichtByNachrichtenManager(any()); + doAnswer(invocation -> invocation.getArgument(0)).when(processor).translateSendPostfachMailCommand(any()); + doReturn(translatedCommandOrder).when(processor).translateReceivePostfachNachrichtCommand(command); + + var commands = process(); + + assertThat(commands).containsExactly(translatedCommandOrder); + } + + private List<Command> process() { + return processor.process(Stream.of(command)).toList(); + } + } + + @Nested + class TestIsNotOutgoingPostfachNachrichtenByNachrichtenManager { + + private final Command matchingCommand = CommandTestFactory.createBuilder() + .order(CommandOrder.CREATE_ATTACHED_ITEM.name()) + .body(Map.of("item", Map.of(PostfachNachrichtHistorieProcessor.DIRECTION, PostfachNachrichtHistorieProcessor.DIRECTION_OUTGOING), + PostfachNachrichtHistorieProcessor.CLIENT, PostfachNachrichtHistorieProcessor.OZGCLOUD_NACHRICHTEN_MANAGER)) + .build(); + + @Test + void shouldReturnFalse() { + var result = processor.isNotOutgoingPostfachNachrichtByNachrichtenManager(matchingCommand); + + assertThat(result).isFalse(); + } + + @Test + void shouldReturnTrueOnOtherOrder() { + var nonMatchingCommand = matchingCommand.toBuilder().order(LoremIpsum.getInstance().getWords(1)).build(); + + var result = processor.isNotOutgoingPostfachNachrichtByNachrichtenManager(nonMatchingCommand); + + assertThat(result).isTrue(); + } + + @Test + void shouldReturnTrueOnIncoming() { + var commandBody = Map.of("item", + Map.of(PostfachNachrichtHistorieProcessor.DIRECTION, PostfachNachrichtHistorieProcessor.DIRECTION_INCOMMING), + PostfachNachrichtHistorieProcessor.CLIENT, PostfachNachrichtHistorieProcessor.OZGCLOUD_NACHRICHTEN_MANAGER); + var nonMatchingCommand = matchingCommand.toBuilder() + .body(commandBody) + .build(); + + var result = processor.isNotOutgoingPostfachNachrichtByNachrichtenManager(nonMatchingCommand); + + assertThat(result).isTrue(); + } + + @Test + void shouldReturnTrueOnOtherClient() { + var commandBody = Map.of("item", + Map.of(PostfachNachrichtHistorieProcessor.DIRECTION, PostfachNachrichtHistorieProcessor.DIRECTION_OUTGOING), + PostfachNachrichtHistorieProcessor.CLIENT, LoremIpsum.getInstance().getWords(1)); + var nonMatchingCommand = matchingCommand.toBuilder() + .body(commandBody) + .build(); + + var result = processor.isNotOutgoingPostfachNachrichtByNachrichtenManager(nonMatchingCommand); + + assertThat(result).isTrue(); + } + } + + @Nested + class TestTranslateSendPostfachMailCommand { + + @Nested + class TestOnHasSendPostfachMailOrder { + @Test + void shouldTranslateOrderToSendPostfachNachricht() { + var command = CommandTestFactory.createBuilder().order(CommandOrder.SEND_POSTFACH_MAIL.name()).build(); + var expectedCommand = command.toBuilder().order(CommandOrder.SEND_POSTFACH_NACHRICHT.name()).build(); + + var resultCommand = processor.translateSendPostfachMailCommand(command); + + assertThat(resultCommand).usingRecursiveComparison().isEqualTo(expectedCommand); + } + } + + @Nested + class TestOnHasNotSendPostfachMailOrder { + @Test + void shouldReturnSameCommand() { + var command = CommandTestFactory.create(); + + var resultCommand = processor.translateSendPostfachMailCommand(command); + + assertThat(resultCommand).isSameAs(command); + } + } + } + + @Nested + class TestTranslateReceivePostfachNachrichtCommand { + + private final Command command = CommandTestFactory.create(); + + @Test + void shouldCallIsIncomingNachrichtbyNachrichtenManager() { + processor.translateReceivePostfachNachrichtCommand(command); + + verify(processor).isIncomingNachrichtByNachrichtenManager(command); + } + + @Test + void shouldTranslateOnIsIncomingNachrichtbyNachrichtenManager() { + doReturn(true).when(processor).isIncomingNachrichtByNachrichtenManager(any()); + var expectedCommand = command.toBuilder().order(CommandOrder.RECEIVE_POSTFACH_NACHRICHT.name()).build(); + + var resultCommand = processor.translateReceivePostfachNachrichtCommand(command); + + assertThat(resultCommand).usingRecursiveComparison().isEqualTo(expectedCommand); + } + + @Test + void shouldNotTranslateOnIsNotIncomingNachrichtbyNachrichtenManager() { + doReturn(false).when(processor).isIncomingNachrichtByNachrichtenManager(any()); + + var resultCommand = processor.translateReceivePostfachNachrichtCommand(command); + + assertThat(resultCommand).isSameAs(command); + } + } + + @Nested + class TestIsIncomingNachrichtByNachrichtenManager { + + private final Command matchingCommand = CommandTestFactory.createBuilder() + .order(CommandOrder.CREATE_ATTACHED_ITEM.name()) + .body(Map.of("item", Map.of(PostfachNachrichtHistorieProcessor.DIRECTION, PostfachNachrichtHistorieProcessor.DIRECTION_INCOMMING), + PostfachNachrichtHistorieProcessor.CLIENT, PostfachNachrichtHistorieProcessor.OZGCLOUD_NACHRICHTEN_MANAGER)) + .build(); + + @Test + void shouldReturnTrue() { + var result = processor.isIncomingNachrichtByNachrichtenManager(matchingCommand); + + assertThat(result).isTrue(); + } + + @Test + void shouldReturnFalseOnOtherOrder() { + var nonMatchingCommand = matchingCommand.toBuilder().order(LoremIpsum.getInstance().getWords(1)).build(); + + var result = processor.isIncomingNachrichtByNachrichtenManager(nonMatchingCommand); + + assertThat(result).isFalse(); + } + + @Test + void shouldReturnFalseOnOutgoing() { + var commandBody = Map.of("item", + Map.of(PostfachNachrichtHistorieProcessor.DIRECTION, PostfachNachrichtHistorieProcessor.DIRECTION_OUTGOING), + PostfachNachrichtHistorieProcessor.CLIENT, PostfachNachrichtHistorieProcessor.OZGCLOUD_NACHRICHTEN_MANAGER); + var nonMatchingCommand = matchingCommand.toBuilder() + .body(commandBody) + .build(); + + var result = processor.isIncomingNachrichtByNachrichtenManager(nonMatchingCommand); + + assertThat(result).isFalse(); + } + + @Test + void shouldReturnFalseOnOtherClient() { + var commandBody = Map.of("item", + Map.of(PostfachNachrichtHistorieProcessor.DIRECTION, PostfachNachrichtHistorieProcessor.DIRECTION_INCOMMING), + PostfachNachrichtHistorieProcessor.CLIENT, LoremIpsum.getInstance().getWords(1)); + var nonMatchingCommand = matchingCommand.toBuilder() + .body(commandBody) + .build(); + + var result = processor.isIncomingNachrichtByNachrichtenManager(nonMatchingCommand); + + assertThat(result).isFalse(); + } + } +} diff --git a/alfa-service/src/test/java/de/ozgcloud/alfa/wiedervorlage/WiedervorlageHistorieProcessorTest.java b/alfa-service/src/test/java/de/ozgcloud/alfa/wiedervorlage/WiedervorlageHistorieProcessorTest.java new file mode 100644 index 0000000000000000000000000000000000000000..78662dc0cd55e2936abb48ea4bc597b4af52167d --- /dev/null +++ b/alfa-service/src/test/java/de/ozgcloud/alfa/wiedervorlage/WiedervorlageHistorieProcessorTest.java @@ -0,0 +1,261 @@ +package de.ozgcloud.alfa.wiedervorlage; + +import static org.assertj.core.api.Assertions.*; +import static org.mockito.ArgumentMatchers.*; +import static org.mockito.Mockito.*; + +import java.util.Map; +import java.util.stream.Stream; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.mockito.Spy; +import org.mockito.stubbing.Answer; + +import com.thedeanda.lorem.LoremIpsum; + +import de.ozgcloud.alfa.common.command.Command; +import de.ozgcloud.alfa.common.command.CommandBodyMapper; +import de.ozgcloud.alfa.common.command.CommandOrder; +import de.ozgcloud.alfa.common.command.CommandTestFactory; +import de.ozgcloud.alfa.common.command.LegacyOrder; +import io.jsonwebtoken.lang.Collections; + +class WiedervorlageHistorieProcessorTest { + + @Spy + private WiedervorlageHistorieProcessor processor; + + @Nested + class TestProcess { + + private final Command command = CommandTestFactory.create(); + private final Command translatedCommand = CommandTestFactory.create(); + private final Answer<Command> doNotTranslate = invocation -> invocation.getArgument(0); + + @BeforeEach + void mockDefault() { + doAnswer(doNotTranslate).when(processor).translateCreateAttachedItem(any()); + doAnswer(doNotTranslate).when(processor).translateUpdateAttachedItem(any()); + doAnswer(doNotTranslate).when(processor).translatePatchAttachedItem(any()); + } + + @Test + void shouldPropagateAllOrders() { + + var commands = processor.process(Stream.of(command)); + + assertThat(commands).containsExactly(command); + } + + @Test + void shouldTranslateCreateAttachedItem() { + processor.process(Stream.of(command)).toList(); + + verify(processor).translateCreateAttachedItem(command); + } + + @Test + void shouldReturnTranslatedCreateAttachedItem() { + doReturn(translatedCommand).when(processor).translateCreateAttachedItem(any()); + + var commands = processor.process(Stream.of(command)).toList(); + + assertThat(commands).containsExactly(translatedCommand); + reset(processor); + } + + @Test + void shouldTranslateUpdateAttachedItem() { + processor.process(Stream.of(command)).toList(); + + verify(processor).translateUpdateAttachedItem(command); + } + + @Test + void shouldReturnTranslatedUpdateAttachedItem() { + doReturn(translatedCommand).when(processor).translateUpdateAttachedItem(any()); + + var commands = processor.process(Stream.of(command)).toList(); + + assertThat(commands).containsExactly(translatedCommand); + reset(processor); + } + + @Test + void shouldTranslatePatchAttachedItem() { + processor.process(Stream.of(command)).toList(); + + verify(processor).translatePatchAttachedItem(command); + } + + @Test + void shouldReturnTranslatedPatchAttachedItem() { + doReturn(translatedCommand).when(processor).translatePatchAttachedItem(any()); + + var commands = processor.process(Stream.of(command)).toList(); + + assertThat(commands).containsExactly(translatedCommand); + reset(processor); + } + } + + @Nested + class TestTranslateCreateAttachedItem { + + private final Map<String, ?> commandBody = Map.of(CommandBodyMapper.ITEM_NAME_PROPERTY, Wiedervorlage.class.getSimpleName()); + private final Command createWiedervorlageCommand = CommandTestFactory.createBuilder() + .order(CommandOrder.CREATE_ATTACHED_ITEM.name()) + .body(commandBody) + .build(); + + @Test + void shouldTranslateOrderToCreateWiedervorlage() { + var expectedCommand = createWiedervorlageCommand.toBuilder().order(LegacyOrder.CREATE_WIEDERVORLAGE).build(); + + var translatedCommand = processor.translateCreateAttachedItem(createWiedervorlageCommand); + + assertThat(translatedCommand).usingRecursiveComparison().isEqualTo(expectedCommand); + } + + @Test + void shouldNotTranslateOtherOrderCommands() { + var command = createWiedervorlageCommand.toBuilder().order(LoremIpsum.getInstance().getWords(1)).build(); + + var translatedCommand = processor.translateCreateAttachedItem(command); + + assertThat(translatedCommand).isSameAs(command); + } + + @Test + void shouldNotTranslateOtherAttachedItems() { + var otherCommandBody = Map.of(CommandBodyMapper.ITEM_NAME_PROPERTY, LoremIpsum.getInstance().getWords(1)); + var command = createWiedervorlageCommand.toBuilder().body(otherCommandBody).build(); + + var translatedCommand = processor.translateCreateAttachedItem(command); + + assertThat(translatedCommand).isSameAs(command); + } + } + + @Nested + class TestTranslateUpdateAttachedItem { + + private final Map<String, ?> commandBody = Map.of(CommandBodyMapper.ITEM_NAME_PROPERTY, Wiedervorlage.class.getSimpleName()); + private final Command editWiedervorlageCommand = CommandTestFactory.createBuilder() + .order(CommandOrder.UPDATE_ATTACHED_ITEM.name()) + .body(commandBody) + .build(); + + @Test + void shouldTranslateOrderToEditWiedervorlage() { + var expectedCommand = editWiedervorlageCommand.toBuilder().order(LegacyOrder.EDIT_WIEDERVORLAGE).build(); + + var translatedCommand = processor.translateUpdateAttachedItem(editWiedervorlageCommand); + + assertThat(translatedCommand).usingRecursiveComparison().isEqualTo(expectedCommand); + } + + @Test + void shouldNotTranslateOtherOrderCommands() { + var command = editWiedervorlageCommand.toBuilder().order(LoremIpsum.getInstance().getWords(1)).build(); + + var translatedCommand = processor.translateUpdateAttachedItem(command); + + assertThat(translatedCommand).isSameAs(command); + } + + @Test + void shouldNotTranslateOtherAttachedItems() { + var otherCommandBody = Map.of(CommandBodyMapper.ITEM_NAME_PROPERTY, LoremIpsum.getInstance().getWords(1)); + var command = editWiedervorlageCommand.toBuilder().body(otherCommandBody).build(); + + var translatedCommand = processor.translateUpdateAttachedItem(command); + + assertThat(translatedCommand).isSameAs(command); + } + } + + @Nested + class TestTranslatePatchAttachedItem { + + private final Map<String, ?> commandBody = Map.of(CommandBodyMapper.ITEM_NAME_PROPERTY, Wiedervorlage.class.getSimpleName()); + private final Command patchWiedervorlageCommand = CommandTestFactory.createBuilder() + .order(CommandOrder.PATCH_ATTACHED_ITEM.name()) + .body(commandBody) + .build(); + + @Test + void shouldCallTranslatePatchWiedervorlage() { + processor.translatePatchAttachedItem(patchWiedervorlageCommand); + + verify(processor).translatePatchWiedervorlage(patchWiedervorlageCommand); + } + + @Test + void shouldReturnTranslatedCommand() { + var translatedCommand = CommandTestFactory.create(); + doReturn(translatedCommand).when(processor).translatePatchWiedervorlage(any()); + + var resultCommand = processor.translatePatchAttachedItem(patchWiedervorlageCommand); + + assertThat(resultCommand).isSameAs(translatedCommand); + } + + @Test + void shouldNotTranslateOtherOrderCommands() { + var command = patchWiedervorlageCommand.toBuilder().order(LoremIpsum.getInstance().getWords(1)).build(); + + var translatedCommand = processor.translatePatchAttachedItem(command); + + assertThat(translatedCommand).isSameAs(command); + } + + @Test + void shouldNotTranslateOtherAttachedItems() { + var otherCommandBody = Map.of(CommandBodyMapper.ITEM_NAME_PROPERTY, LoremIpsum.getInstance().getWords(1)); + var command = patchWiedervorlageCommand.toBuilder().body(otherCommandBody).build(); + + var translatedCommand = processor.translatePatchAttachedItem(command); + + assertThat(translatedCommand).isSameAs(command); + } + } + + @Nested + class TestTranslatePatchWiedervorlage { + + @Test + void shouldReturnWiedervorlageErledigenCommand() { + var commandBody = Map.of(CommandBodyMapper.ITEM_PROPERTY, Map.of(Wiedervorlage.DONE_FIELD, true)); + var command = CommandTestFactory.createBuilder().body(commandBody).build(); + var expectedCommand = command.toBuilder().order(LegacyOrder.WIEDERVORLAGE_ERLEDIGEN); + + var translatedCommand = processor.translatePatchWiedervorlage(command); + + assertThat(translatedCommand).usingRecursiveComparison().isEqualTo(expectedCommand); + } + + @Test + void shouldReturnWiedervorlageWiedereroeffnenCommand() { + var commandBody = Map.of(CommandBodyMapper.ITEM_PROPERTY, Map.of(Wiedervorlage.DONE_FIELD, false)); + var command = CommandTestFactory.createBuilder().body(commandBody).build(); + var expectedCommand = command.toBuilder().order(LegacyOrder.WIEDERVORLAGE_WIEDEREROEFFNEN); + + var translatedCommand = processor.translatePatchWiedervorlage(command); + + assertThat(translatedCommand).usingRecursiveComparison().isEqualTo(expectedCommand); + } + + @Test + void shouldNotTranslateOnMissingBoolean() { + var commandBody = Map.of(CommandBodyMapper.ITEM_PROPERTY, Collections.emptyMap()); + var command = CommandTestFactory.createBuilder().body(commandBody).build(); + + var translatedCommand = processor.translatePatchWiedervorlage(command); + + assertThat(translatedCommand).isSameAs(command); + } + } +}