From 885de80b3e6276f31b5d5673b2596e2ed5762c2f Mon Sep 17 00:00:00 2001 From: Caroline Jeandat Date: Wed, 10 Jun 2026 12:46:50 +0200 Subject: [PATCH 1/9] Implement Strategy Design Pattern for process configs Signed-off-by: Caroline Jeandat --- .../controllers/ProcessConfigController.java | 5 +- .../error/MonitorServerBusinessErrorCode.java | 1 + .../error/MonitorServerExceptionHandler.java | 1 + .../processconfig/LoadFlowConfigMapper.java | 2 +- .../processconfig/ProcessConfigMapper.java | 21 +++ .../SecurityAnalysisConfigMapper.java | 2 +- .../AbstractProcessConfigHandler.java | 75 ++++++++ .../processconfig/LoadFlowConfigHandler.java | 38 ++++ .../processconfig/ProcessConfigHandler.java | 32 ++++ .../processconfig/ProcessConfigService.java | 174 +++++------------- .../SecurityAnalysisConfigHandler.java | 41 +++++ .../ProcessConfigControllerTest.java | 13 +- .../MonitorServerExceptionHandlerTest.java | 2 + .../AbstractProcessConfigMapperTest.java | 19 ++ .../ProcessConfigHandlerTest.java | 26 +++ .../ProcessConfigServiceTest.java | 118 ++++++------ 16 files changed, 374 insertions(+), 196 deletions(-) create mode 100644 monitor-server/src/main/java/org/gridsuite/monitor/server/mappers/processconfig/ProcessConfigMapper.java create mode 100644 monitor-server/src/main/java/org/gridsuite/monitor/server/services/processconfig/AbstractProcessConfigHandler.java create mode 100644 monitor-server/src/main/java/org/gridsuite/monitor/server/services/processconfig/LoadFlowConfigHandler.java create mode 100644 monitor-server/src/main/java/org/gridsuite/monitor/server/services/processconfig/ProcessConfigHandler.java create mode 100644 monitor-server/src/main/java/org/gridsuite/monitor/server/services/processconfig/SecurityAnalysisConfigHandler.java create mode 100644 monitor-server/src/test/java/org/gridsuite/monitor/server/mappers/processconfig/AbstractProcessConfigMapperTest.java create mode 100644 monitor-server/src/test/java/org/gridsuite/monitor/server/services/processconfig/ProcessConfigHandlerTest.java diff --git a/monitor-server/src/main/java/org/gridsuite/monitor/server/controllers/ProcessConfigController.java b/monitor-server/src/main/java/org/gridsuite/monitor/server/controllers/ProcessConfigController.java index e54f660a..acad2ffe 100644 --- a/monitor-server/src/main/java/org/gridsuite/monitor/server/controllers/ProcessConfigController.java +++ b/monitor-server/src/main/java/org/gridsuite/monitor/server/controllers/ProcessConfigController.java @@ -18,7 +18,6 @@ import org.gridsuite.monitor.commons.types.processexecution.ProcessType; import org.gridsuite.monitor.server.dto.processconfig.ProcessConfigComparison; import org.gridsuite.monitor.server.services.processconfig.ProcessConfigService; -import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.DeleteMapping; @@ -134,7 +133,7 @@ public ResponseEntity compareProcessConfigs( @Parameter(description = "First process config UUID") @RequestParam("uuid1") UUID uuid1, @Parameter(description = "Second process config UUID") @RequestParam("uuid2") UUID uuid2) { - Optional comparison = processConfigService.compareProcessConfigs(uuid1, uuid2); - return comparison.map(c -> ResponseEntity.status(HttpStatus.OK).body(c)).orElseGet(() -> ResponseEntity.status(HttpStatus.NOT_FOUND).build()); + ProcessConfigComparison comparison = processConfigService.compareProcessConfigs(uuid1, uuid2); + return ResponseEntity.ok().body(comparison); } } diff --git a/monitor-server/src/main/java/org/gridsuite/monitor/server/error/MonitorServerBusinessErrorCode.java b/monitor-server/src/main/java/org/gridsuite/monitor/server/error/MonitorServerBusinessErrorCode.java index 4315e801..c6e72d5a 100644 --- a/monitor-server/src/main/java/org/gridsuite/monitor/server/error/MonitorServerBusinessErrorCode.java +++ b/monitor-server/src/main/java/org/gridsuite/monitor/server/error/MonitorServerBusinessErrorCode.java @@ -12,6 +12,7 @@ * @author Franck Lecuyer */ public enum MonitorServerBusinessErrorCode implements BusinessErrorCode { + PROCESS_CONFIG_NOT_FOUND("monitor.server.processConfigNotFound"), DIFFERENT_PROCESS_CONFIG_TYPE("monitor.server.differentProcessConfigType"); private final String code; diff --git a/monitor-server/src/main/java/org/gridsuite/monitor/server/error/MonitorServerExceptionHandler.java b/monitor-server/src/main/java/org/gridsuite/monitor/server/error/MonitorServerExceptionHandler.java index 05aa2258..4713ef9d 100644 --- a/monitor-server/src/main/java/org/gridsuite/monitor/server/error/MonitorServerExceptionHandler.java +++ b/monitor-server/src/main/java/org/gridsuite/monitor/server/error/MonitorServerExceptionHandler.java @@ -35,6 +35,7 @@ protected MonitorServerBusinessErrorCode getBusinessCode(MonitorServerException @Override protected HttpStatus mapStatus(MonitorServerBusinessErrorCode errorCode) { return switch (errorCode) { + case PROCESS_CONFIG_NOT_FOUND -> HttpStatus.NOT_FOUND; case DIFFERENT_PROCESS_CONFIG_TYPE -> HttpStatus.BAD_REQUEST; }; } diff --git a/monitor-server/src/main/java/org/gridsuite/monitor/server/mappers/processconfig/LoadFlowConfigMapper.java b/monitor-server/src/main/java/org/gridsuite/monitor/server/mappers/processconfig/LoadFlowConfigMapper.java index cc55dfac..d8991e0c 100644 --- a/monitor-server/src/main/java/org/gridsuite/monitor/server/mappers/processconfig/LoadFlowConfigMapper.java +++ b/monitor-server/src/main/java/org/gridsuite/monitor/server/mappers/processconfig/LoadFlowConfigMapper.java @@ -16,7 +16,7 @@ * @author Franck Lecuyer */ @Mapper(componentModel = "spring") -public interface LoadFlowConfigMapper { +public interface LoadFlowConfigMapper extends ProcessConfigMapper { @Mapping(target = "processType", expression = "java(dto.processType())") LoadFlowConfigEntity toEntity(LoadFlowConfig dto); diff --git a/monitor-server/src/main/java/org/gridsuite/monitor/server/mappers/processconfig/ProcessConfigMapper.java b/monitor-server/src/main/java/org/gridsuite/monitor/server/mappers/processconfig/ProcessConfigMapper.java new file mode 100644 index 00000000..5dba8722 --- /dev/null +++ b/monitor-server/src/main/java/org/gridsuite/monitor/server/mappers/processconfig/ProcessConfigMapper.java @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2026, RTE (http://www.rte-france.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ +package org.gridsuite.monitor.server.mappers.processconfig; + +import org.gridsuite.monitor.commons.types.processconfig.ProcessConfig; +import org.gridsuite.monitor.server.entities.processconfig.ProcessConfigEntity; + +/** + * @author Caroline Jeandat {@literal } + */ +public interface ProcessConfigMapper { + E toEntity(C dto); + + C toDto(E entity); + + void updateEntityFromDto(C dto, E entity); +} diff --git a/monitor-server/src/main/java/org/gridsuite/monitor/server/mappers/processconfig/SecurityAnalysisConfigMapper.java b/monitor-server/src/main/java/org/gridsuite/monitor/server/mappers/processconfig/SecurityAnalysisConfigMapper.java index c24c976b..d4818af8 100644 --- a/monitor-server/src/main/java/org/gridsuite/monitor/server/mappers/processconfig/SecurityAnalysisConfigMapper.java +++ b/monitor-server/src/main/java/org/gridsuite/monitor/server/mappers/processconfig/SecurityAnalysisConfigMapper.java @@ -16,7 +16,7 @@ * @author Radouane Khouadri */ @Mapper(componentModel = "spring") -public interface SecurityAnalysisConfigMapper { +public interface SecurityAnalysisConfigMapper extends ProcessConfigMapper { @Mapping(target = "processType", expression = "java(dto.processType())") SecurityAnalysisConfigEntity toEntity(SecurityAnalysisConfig dto); diff --git a/monitor-server/src/main/java/org/gridsuite/monitor/server/services/processconfig/AbstractProcessConfigHandler.java b/monitor-server/src/main/java/org/gridsuite/monitor/server/services/processconfig/AbstractProcessConfigHandler.java new file mode 100644 index 00000000..f69da8b2 --- /dev/null +++ b/monitor-server/src/main/java/org/gridsuite/monitor/server/services/processconfig/AbstractProcessConfigHandler.java @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2026, RTE (http://www.rte-france.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ +package org.gridsuite.monitor.server.services.processconfig; + +import org.gridsuite.monitor.commons.types.processconfig.ProcessConfig; +import org.gridsuite.monitor.server.dto.processconfig.ProcessConfigFieldComparison; +import org.gridsuite.monitor.server.entities.processconfig.ProcessConfigEntity; +import org.gridsuite.monitor.server.mappers.processconfig.ProcessConfigMapper; + +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +/** + * @author Caroline Jeandat {@literal } + */ +public abstract class AbstractProcessConfigHandler> + implements ProcessConfigHandler { + + protected final M mapper; + + protected AbstractProcessConfigHandler(M mapper) { + this.mapper = mapper; + } + + @Override + public void update(E entity, C processConfig) { + mapper.updateEntityFromDto(processConfig, entity); + } + + @Override + public E copyEntity(E sourceEntity) { + return toEntity(toProcessConfig(sourceEntity)); + } + + @Override + public E toEntity(C processConfig) { + return mapper.toEntity(processConfig); + } + + @Override + public C toProcessConfig(E entity) { + return mapper.toDto(entity); + } + + @Override + public List computeDifferences(E entity1, E entity2) { + C config1 = toProcessConfig(entity1); + C config2 = toProcessConfig(entity2); + List differences = new ArrayList<>(); + + // Compare modifications + addFieldComparison(config1.modificationUuids(), config2.modificationUuids(), differences, "modifications"); + + // Compare other fields + addProcessConfigSpecificFieldsComparison(config1, config2, differences); + + return differences; + } + + protected abstract void addProcessConfigSpecificFieldsComparison(C config1, C config2, List differences); + + protected void addFieldComparison(Object value1, Object value2, List differences, String fieldName) { + differences.add(new ProcessConfigFieldComparison( + fieldName, + Objects.equals(value1, value2), + value1, + value2 + )); + } +} diff --git a/monitor-server/src/main/java/org/gridsuite/monitor/server/services/processconfig/LoadFlowConfigHandler.java b/monitor-server/src/main/java/org/gridsuite/monitor/server/services/processconfig/LoadFlowConfigHandler.java new file mode 100644 index 00000000..6cb4be5f --- /dev/null +++ b/monitor-server/src/main/java/org/gridsuite/monitor/server/services/processconfig/LoadFlowConfigHandler.java @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2026, RTE (http://www.rte-france.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ +package org.gridsuite.monitor.server.services.processconfig; + +import org.gridsuite.monitor.commons.types.processconfig.LoadFlowConfig; +import org.gridsuite.monitor.commons.types.processexecution.ProcessType; +import org.gridsuite.monitor.server.dto.processconfig.ProcessConfigFieldComparison; +import org.gridsuite.monitor.server.entities.processconfig.LoadFlowConfigEntity; +import org.gridsuite.monitor.server.mappers.processconfig.LoadFlowConfigMapper; +import org.springframework.stereotype.Service; + +import java.util.List; + +/** + * @author Caroline Jeandat {@literal } + */ +@Service +public class LoadFlowConfigHandler extends AbstractProcessConfigHandler { + + public LoadFlowConfigHandler(LoadFlowConfigMapper mapper) { + super(mapper); + } + + @Override + public ProcessType getProcessType() { + return ProcessType.LOADFLOW; + } + + @Override + protected void addProcessConfigSpecificFieldsComparison(LoadFlowConfig config1, LoadFlowConfig config2, List differences) { + // Compare loadflow parameters + addFieldComparison(config1.loadflowParametersUuid(), config2.loadflowParametersUuid(), differences, "loadflowParameters"); + } +} diff --git a/monitor-server/src/main/java/org/gridsuite/monitor/server/services/processconfig/ProcessConfigHandler.java b/monitor-server/src/main/java/org/gridsuite/monitor/server/services/processconfig/ProcessConfigHandler.java new file mode 100644 index 00000000..38e3ae23 --- /dev/null +++ b/monitor-server/src/main/java/org/gridsuite/monitor/server/services/processconfig/ProcessConfigHandler.java @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2026, RTE (http://www.rte-france.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ +package org.gridsuite.monitor.server.services.processconfig; + +import org.gridsuite.monitor.commons.types.processconfig.ProcessConfig; +import org.gridsuite.monitor.commons.types.processexecution.ProcessType; +import org.gridsuite.monitor.server.dto.processconfig.ProcessConfigFieldComparison; +import org.gridsuite.monitor.server.entities.processconfig.ProcessConfigEntity; + +import java.util.List; + +/** + * @author Caroline Jeandat {@literal } + */ +public interface ProcessConfigHandler { + + ProcessType getProcessType(); + + void update(E entity, C processConfig); + + E copyEntity(E sourceEntity); + + E toEntity(C processConfig); + + C toProcessConfig(E entity); + + List computeDifferences(E entity1, E entity2); +} diff --git a/monitor-server/src/main/java/org/gridsuite/monitor/server/services/processconfig/ProcessConfigService.java b/monitor-server/src/main/java/org/gridsuite/monitor/server/services/processconfig/ProcessConfigService.java index eeb02ab5..9332ca24 100644 --- a/monitor-server/src/main/java/org/gridsuite/monitor/server/services/processconfig/ProcessConfigService.java +++ b/monitor-server/src/main/java/org/gridsuite/monitor/server/services/processconfig/ProcessConfigService.java @@ -6,27 +6,24 @@ */ package org.gridsuite.monitor.server.services.processconfig; -import org.gridsuite.monitor.commons.types.processconfig.LoadFlowConfig; import org.gridsuite.monitor.commons.types.processconfig.ProcessConfig; -import org.gridsuite.monitor.commons.types.processconfig.SecurityAnalysisConfig; import org.gridsuite.monitor.commons.types.processexecution.ProcessType; import org.gridsuite.monitor.server.dto.processconfig.MetadataInfos; import org.gridsuite.monitor.server.dto.processconfig.ProcessConfigComparison; import org.gridsuite.monitor.server.dto.processconfig.ProcessConfigFieldComparison; import org.gridsuite.monitor.server.dto.processconfig.PersistedProcessConfig; -import org.gridsuite.monitor.server.entities.processconfig.LoadFlowConfigEntity; import org.gridsuite.monitor.server.entities.processconfig.ProcessConfigEntity; -import org.gridsuite.monitor.server.entities.processconfig.SecurityAnalysisConfigEntity; import org.gridsuite.monitor.server.error.MonitorServerException; -import org.gridsuite.monitor.server.mappers.processconfig.LoadFlowConfigMapper; -import org.gridsuite.monitor.server.mappers.processconfig.SecurityAnalysisConfigMapper; import org.gridsuite.monitor.server.repositories.ProcessConfigRepository; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.util.*; +import java.util.function.Function; +import java.util.stream.Collectors; import static org.gridsuite.monitor.server.error.MonitorServerBusinessErrorCode.DIFFERENT_PROCESS_CONFIG_TYPE; +import static org.gridsuite.monitor.server.error.MonitorServerBusinessErrorCode.PROCESS_CONFIG_NOT_FOUND; /** * @author Franck Lecuyer @@ -34,37 +31,42 @@ @Service public class ProcessConfigService { private final ProcessConfigRepository processConfigRepository; - private final SecurityAnalysisConfigMapper securityAnalysisConfigMapper; - private final LoadFlowConfigMapper loadFlowConfigMapper; + private final Map> processConfigHandlers; public ProcessConfigService(ProcessConfigRepository processConfigRepository, - SecurityAnalysisConfigMapper securityAnalysisConfigMapper, - LoadFlowConfigMapper loadFlowConfigMapper) { + List> listHandlers) { this.processConfigRepository = processConfigRepository; - this.securityAnalysisConfigMapper = securityAnalysisConfigMapper; - this.loadFlowConfigMapper = loadFlowConfigMapper; + this.processConfigHandlers = listHandlers.stream().collect(Collectors.toMap( + ProcessConfigHandler::getProcessType, Function.identity() + )); + } + + @SuppressWarnings("unchecked") + private ProcessConfigHandler getHandler(ProcessType processType) { + ProcessConfigHandler handler = processConfigHandlers.get(processType); + if (handler == null) { + throw new IllegalArgumentException("Unsupported process config type: " + processType); + } + return (ProcessConfigHandler) handler; } @Transactional public UUID createProcessConfig(ProcessConfig processConfig) { - return doCreateProcessConfig(processConfig); + ProcessConfigEntity entity = getHandler(processConfig.processType()).toEntity(processConfig); + return processConfigRepository.save(entity).getId(); } - private UUID doCreateProcessConfig(ProcessConfig processConfig) { - switch (processConfig) { - case SecurityAnalysisConfig sac -> { - return processConfigRepository.save(securityAnalysisConfigMapper.toEntity(sac)).getId(); - } - case LoadFlowConfig lfc -> { - return processConfigRepository.save(loadFlowConfigMapper.toEntity(lfc)).getId(); - } - default -> throw new IllegalArgumentException("Unsupported process config type: " + processConfig.processType()); - } + @Transactional(readOnly = true) + public Optional getProcessConfig(UUID processConfigUuid) { + return processConfigRepository.findById(processConfigUuid) + .map(this::toPersistedProcessConfig); // TODO: renvoyer l'erreur not found ici au lieu de se trimbaler un Optional ? } @Transactional(readOnly = true) - public Optional getProcessConfig(UUID processConfigUuid) { - return processConfigRepository.findById(processConfigUuid).map(this::toPersistedProcessConfig); + public List getProcessConfigs(ProcessType processType) { + return processConfigRepository.findAllByProcessType(processType).stream() + .map(this::toPersistedProcessConfig) + .toList(); } @Transactional(readOnly = true) @@ -81,21 +83,18 @@ public Optional updateProcessConfig(UUID processConfigUuid, ProcessConfig if (entity.getProcessType() != processConfig.processType()) { throw new IllegalArgumentException("Process config type mismatch : " + entity.getProcessType()); } - switch (processConfig) { - case SecurityAnalysisConfig sac -> - securityAnalysisConfigMapper.updateEntityFromDto(sac, (SecurityAnalysisConfigEntity) entity); - case LoadFlowConfig lfc -> - loadFlowConfigMapper.updateEntityFromDto(lfc, (LoadFlowConfigEntity) entity); - default -> throw new IllegalArgumentException("Unsupported process config type: " + processConfig.processType()); - } + getHandler(processConfig.processType()).update(entity, processConfig); return processConfigUuid; - }); + }); // TODO: renvoyer l'erreur not found ici au lieu de se trimbaler un Optional ? } @Transactional public Optional duplicateProcessConfig(UUID sourceProcessConfigUuid) { return processConfigRepository.findById(sourceProcessConfigUuid) - .map(sourceEntity -> doCreateProcessConfig(toProcessConfig(sourceEntity))); + .map(sourceEntity -> { + ProcessConfigEntity entity = getHandler(sourceEntity.getProcessType()).copyEntity(sourceEntity); + return processConfigRepository.save(entity).getId(); + }); // TODO: renvoyer l'erreur not found ici au lieu de se trimbaler un Optional ? } @Transactional @@ -105,108 +104,31 @@ public Optional deleteProcessConfig(UUID processConfigUuid) { return Optional.of(processConfigUuid); } else { return Optional.empty(); - } - } - - @Transactional(readOnly = true) - public List getProcessConfigs(ProcessType processType) { - return processConfigRepository.findAllByProcessType(processType).stream() - .map(this::toPersistedProcessConfig) - .toList(); - } - - private ProcessConfig toProcessConfig(ProcessConfigEntity entity) { - return switch (entity) { - case SecurityAnalysisConfigEntity sae -> securityAnalysisConfigMapper.toDto(sae); - case LoadFlowConfigEntity lfe -> loadFlowConfigMapper.toDto(lfe); - default -> throw new IllegalArgumentException("Unsupported entity type: " + entity.getProcessType()); - }; + } // TODO: renvoyer l'erreur not found ici au lieu de se trimbaler un Optional ? } private PersistedProcessConfig toPersistedProcessConfig(ProcessConfigEntity entity) { - return new PersistedProcessConfig(entity.getId(), toProcessConfig(entity)); + ProcessConfig processConfig = getHandler(entity.getProcessType()).toProcessConfig(entity); + return new PersistedProcessConfig(entity.getId(), processConfig); } @Transactional(readOnly = true) - public Optional compareProcessConfigs(UUID uuid1, UUID uuid2) { - Optional processConfigEntity1 = processConfigRepository.findById(uuid1); - Optional processConfigEntity2 = processConfigRepository.findById(uuid2); - - if (processConfigEntity1.isEmpty() || processConfigEntity2.isEmpty()) { - return Optional.empty(); - } - - ProcessConfig processConfig1 = toProcessConfig(processConfigEntity1.get()); - ProcessConfig processConfig2 = toProcessConfig(processConfigEntity2.get()); - - if (processConfig1.processType() != processConfig2.processType()) { + public ProcessConfigComparison compareProcessConfigs(UUID uuid1, UUID uuid2) { + ProcessConfigEntity entity1 = processConfigRepository.findById(uuid1) + .orElseThrow(() -> new MonitorServerException(PROCESS_CONFIG_NOT_FOUND, "Process config not found", + Map.of("processConfigUuid", uuid1))); + ProcessConfigEntity entity2 = processConfigRepository.findById(uuid2) + .orElseThrow(() -> new MonitorServerException(PROCESS_CONFIG_NOT_FOUND, "Process config not found", + Map.of("processConfigUuid", uuid2))); + + if (entity1.getProcessType() != entity2.getProcessType()) { throw new MonitorServerException(DIFFERENT_PROCESS_CONFIG_TYPE, "Cannot compare different process config types", - Map.of("processConfigEntity1Type", processConfig1.processType(), "processConfigEntity2Type", processConfig2.processType())); + Map.of("processConfigEntity1Type", entity1.getProcessType(), "processConfigEntity2Type", entity2.getProcessType())); } - List differences = switch (processConfig1) { - case SecurityAnalysisConfig sac1 -> compareSecurityAnalysisConfigs(sac1, (SecurityAnalysisConfig) processConfig2); - case LoadFlowConfig lfc1 -> compareLoadFlowConfigs(lfc1, (LoadFlowConfig) processConfig2); - default -> throw new IllegalArgumentException("Unsupported process config type: " + processConfig1.processType()); - }; - + List differences = getHandler(entity1.getProcessType()).computeDifferences(entity1, entity2); boolean identical = differences.stream().allMatch(ProcessConfigFieldComparison::identical); - return Optional.of(new ProcessConfigComparison(uuid1, uuid2, identical, differences)); - } - - private void compareConfigsModifications(ProcessConfig config1, ProcessConfig config2, List differences) { - boolean modificationsIdentical = Objects.equals(config1.modificationUuids(), config2.modificationUuids()); - differences.add(new ProcessConfigFieldComparison( - "modifications", - modificationsIdentical, - config1.modificationUuids(), - config2.modificationUuids() - )); - } - - private List compareSecurityAnalysisConfigs(SecurityAnalysisConfig config1, SecurityAnalysisConfig config2) { - List differences = new ArrayList<>(); - - // Compare modifications - compareConfigsModifications(config1, config2, differences); - - // Compare security analysis parameters - boolean securityAnalysisParametersIdentical = Objects.equals(config1.securityAnalysisParametersUuid(), config2.securityAnalysisParametersUuid()); - differences.add(new ProcessConfigFieldComparison( - "securityAnalysisParameters", - securityAnalysisParametersIdentical, - config1.securityAnalysisParametersUuid(), - config2.securityAnalysisParametersUuid() - )); - - // Compare loadflow parameters - boolean loadflowParametersIdentical = Objects.equals(config1.loadflowParametersUuid(), config2.loadflowParametersUuid()); - differences.add(new ProcessConfigFieldComparison( - "loadflowParameters", - loadflowParametersIdentical, - config1.loadflowParametersUuid(), - config2.loadflowParametersUuid() - )); - - return differences; - } - - private List compareLoadFlowConfigs(LoadFlowConfig config1, LoadFlowConfig config2) { - List differences = new ArrayList<>(); - - // Compare modifications - compareConfigsModifications(config1, config2, differences); - - // Compare loadflow parameters - boolean loadflowParametersIdentical = Objects.equals(config1.loadflowParametersUuid(), config2.loadflowParametersUuid()); - differences.add(new ProcessConfigFieldComparison( - "loadflowParameters", - loadflowParametersIdentical, - config1.loadflowParametersUuid(), - config2.loadflowParametersUuid() - )); - - return differences; + return new ProcessConfigComparison(uuid1, uuid2, identical, differences); } } diff --git a/monitor-server/src/main/java/org/gridsuite/monitor/server/services/processconfig/SecurityAnalysisConfigHandler.java b/monitor-server/src/main/java/org/gridsuite/monitor/server/services/processconfig/SecurityAnalysisConfigHandler.java new file mode 100644 index 00000000..5049a726 --- /dev/null +++ b/monitor-server/src/main/java/org/gridsuite/monitor/server/services/processconfig/SecurityAnalysisConfigHandler.java @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2026, RTE (http://www.rte-france.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ +package org.gridsuite.monitor.server.services.processconfig; + +import org.gridsuite.monitor.commons.types.processconfig.SecurityAnalysisConfig; +import org.gridsuite.monitor.commons.types.processexecution.ProcessType; +import org.gridsuite.monitor.server.dto.processconfig.ProcessConfigFieldComparison; +import org.gridsuite.monitor.server.entities.processconfig.SecurityAnalysisConfigEntity; +import org.gridsuite.monitor.server.mappers.processconfig.SecurityAnalysisConfigMapper; +import org.springframework.stereotype.Service; + +import java.util.List; + +/** + * @author Caroline Jeandat {@literal } + */ +@Service +public class SecurityAnalysisConfigHandler extends AbstractProcessConfigHandler { + + public SecurityAnalysisConfigHandler(SecurityAnalysisConfigMapper mapper) { + super(mapper); + } + + @Override + public ProcessType getProcessType() { + return ProcessType.SECURITY_ANALYSIS; + } + + @Override + protected void addProcessConfigSpecificFieldsComparison(SecurityAnalysisConfig config1, SecurityAnalysisConfig config2, List differences) { + // Compare loadflow parameters + addFieldComparison(config1.loadflowParametersUuid(), config2.loadflowParametersUuid(), differences, "loadflowParameters"); + + // Compare security analysis parameters + addFieldComparison(config1.securityAnalysisParametersUuid(), config2.securityAnalysisParametersUuid(), differences, "securityAnalysisParameters"); + } +} diff --git a/monitor-server/src/test/java/org/gridsuite/monitor/server/controllers/ProcessConfigControllerTest.java b/monitor-server/src/test/java/org/gridsuite/monitor/server/controllers/ProcessConfigControllerTest.java index 848f320e..73060c48 100644 --- a/monitor-server/src/test/java/org/gridsuite/monitor/server/controllers/ProcessConfigControllerTest.java +++ b/monitor-server/src/test/java/org/gridsuite/monitor/server/controllers/ProcessConfigControllerTest.java @@ -25,10 +25,12 @@ import org.springframework.test.web.servlet.MockMvc; import java.util.List; +import java.util.Map; import java.util.Optional; import java.util.UUID; import static org.gridsuite.monitor.server.error.MonitorServerBusinessErrorCode.DIFFERENT_PROCESS_CONFIG_TYPE; +import static org.gridsuite.monitor.server.error.MonitorServerBusinessErrorCode.PROCESS_CONFIG_NOT_FOUND; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -272,7 +274,7 @@ void compareProcessConfigsShouldReturnComparisonResult() throws Exception { ); when(processConfigService.compareProcessConfigs(uuid1, uuid2)) - .thenReturn(Optional.of(comparison)); + .thenReturn(comparison); mockMvc.perform(get("/v1/process-configs/compare") .param("uuid1", uuid1.toString()) @@ -285,12 +287,13 @@ void compareProcessConfigsShouldReturnComparisonResult() throws Exception { .andExpect(jsonPath("$.identical").value(true)) .andExpect(jsonPath("$.differences").isArray()) .andExpect(jsonPath("$.differences.length()").value(3)); + // TODO: remplacer les jsonPath par la récupération du MvcResult et égalité avec l'objet de référence verify(processConfigService).compareProcessConfigs(uuid1, uuid2); } @Test - void compareProcessConfigsShouldReturnDifferences() throws Exception { + void compareProcessConfigsShouldReturnDifferences() throws Exception { // TODO: quelle différence avec le test d'avant ? UUID uuid1 = UUID.randomUUID(); UUID uuid2 = UUID.randomUUID(); List modificationUuids1 = List.of(UUID.randomUUID()); @@ -306,7 +309,7 @@ void compareProcessConfigsShouldReturnDifferences() throws Exception { ); when(processConfigService.compareProcessConfigs(uuid1, uuid2)) - .thenReturn(Optional.of(comparison)); + .thenReturn(comparison); mockMvc.perform(get("/v1/process-configs/compare") .param("uuid1", uuid1.toString()) @@ -316,6 +319,7 @@ void compareProcessConfigsShouldReturnDifferences() throws Exception { .andExpect(jsonPath("$.identical").value(false)) .andExpect(jsonPath("$.differences[0].field").value("modifications")) .andExpect(jsonPath("$.differences[0].identical").value(false)); + // TODO: remplacer les jsonPath par la récupération du MvcResult et égalité avec l'objet de référence verify(processConfigService).compareProcessConfigs(uuid1, uuid2); } @@ -326,7 +330,8 @@ void compareProcessConfigsShouldReturn404WhenConfigNotFound() throws Exception { UUID uuid2 = UUID.randomUUID(); when(processConfigService.compareProcessConfigs(uuid1, uuid2)) - .thenReturn(Optional.empty()); + .thenThrow(new MonitorServerException(PROCESS_CONFIG_NOT_FOUND, "Process config not found", + Map.of("processConfigUuid", uuid1))); mockMvc.perform(get("/v1/process-configs/compare") .param("uuid1", uuid1.toString()) diff --git a/monitor-server/src/test/java/org/gridsuite/monitor/server/error/MonitorServerExceptionHandlerTest.java b/monitor-server/src/test/java/org/gridsuite/monitor/server/error/MonitorServerExceptionHandlerTest.java index d507307c..07663c43 100644 --- a/monitor-server/src/test/java/org/gridsuite/monitor/server/error/MonitorServerExceptionHandlerTest.java +++ b/monitor-server/src/test/java/org/gridsuite/monitor/server/error/MonitorServerExceptionHandlerTest.java @@ -38,4 +38,6 @@ void mapsBadRequestBusinessErrorToStatus() { assertThat(response.getBody()).isNotNull(); assertEquals("monitor.server.differentProcessConfigType", response.getBody().getBusinessErrorCode()); } + + // TODO: test PROCESS_CONFIG_NOT_FOUND } diff --git a/monitor-server/src/test/java/org/gridsuite/monitor/server/mappers/processconfig/AbstractProcessConfigMapperTest.java b/monitor-server/src/test/java/org/gridsuite/monitor/server/mappers/processconfig/AbstractProcessConfigMapperTest.java new file mode 100644 index 00000000..da3a156d --- /dev/null +++ b/monitor-server/src/test/java/org/gridsuite/monitor/server/mappers/processconfig/AbstractProcessConfigMapperTest.java @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2026, RTE (http://www.rte-france.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ +package org.gridsuite.monitor.server.mappers.processconfig; + +/** + * @author Caroline Jeandat {@literal } + */ +public abstract class AbstractProcessConfigMapperTest { + // TODO + // E toEntity(C dto); + + // C toDto(E entity); + + // void updateEntityFromDto(C dto, E entity); +} diff --git a/monitor-server/src/test/java/org/gridsuite/monitor/server/services/processconfig/ProcessConfigHandlerTest.java b/monitor-server/src/test/java/org/gridsuite/monitor/server/services/processconfig/ProcessConfigHandlerTest.java new file mode 100644 index 00000000..4c9fc035 --- /dev/null +++ b/monitor-server/src/test/java/org/gridsuite/monitor/server/services/processconfig/ProcessConfigHandlerTest.java @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2026, RTE (http://www.rte-france.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ +package org.gridsuite.monitor.server.services.processconfig; + +/** + * @author Caroline Jeandat {@literal } + */ +public class ProcessConfigHandlerTest { + // TODO, with parameterized tests sauf pour computeDifferences (seul qui est vraiment différent) + + // ProcessType getProcessType(); + + // void update(E entity, C processConfig); + + // E copyEntity(E sourceEntity); + + // E toEntity(C processConfig); + + // C toProcessConfig(E entity); + + // List computeDifferences(E entity1, E entity2); +} diff --git a/monitor-server/src/test/java/org/gridsuite/monitor/server/services/processconfig/ProcessConfigServiceTest.java b/monitor-server/src/test/java/org/gridsuite/monitor/server/services/processconfig/ProcessConfigServiceTest.java index 81afc2fa..d0ebb9d1 100644 --- a/monitor-server/src/test/java/org/gridsuite/monitor/server/services/processconfig/ProcessConfigServiceTest.java +++ b/monitor-server/src/test/java/org/gridsuite/monitor/server/services/processconfig/ProcessConfigServiceTest.java @@ -24,7 +24,6 @@ import org.junit.jupiter.api.extension.ExtendWith; import org.mapstruct.factory.Mappers; import org.mockito.ArgumentCaptor; -import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.Spy; import org.mockito.junit.jupiter.MockitoExtension; @@ -37,6 +36,7 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.assertj.core.api.AssertionsForClassTypes.catchThrowable; import static org.gridsuite.monitor.server.error.MonitorServerBusinessErrorCode.DIFFERENT_PROCESS_CONFIG_TYPE; +import static org.junit.jupiter.api.Assertions.assertEquals; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.*; @@ -48,20 +48,24 @@ class ProcessConfigServiceTest { @Mock private ProcessConfigRepository processConfigRepository; - @InjectMocks private ProcessConfigService processConfigService; private SecurityAnalysisConfig securityAnalysisConfig; private LoadFlowConfig loadFlowConfig; @Spy - private final SecurityAnalysisConfigMapper securityAnalysisConfigMapper = Mappers.getMapper(SecurityAnalysisConfigMapper.class); + private final SecurityAnalysisConfigHandler securityAnalysisConfigHandler = new SecurityAnalysisConfigHandler(Mappers.getMapper(SecurityAnalysisConfigMapper.class)); @Spy - private final LoadFlowConfigMapper loadFlowConfigMapper = Mappers.getMapper(LoadFlowConfigMapper.class); + private final LoadFlowConfigHandler loadFlowConfigHandler = new LoadFlowConfigHandler(Mappers.getMapper(LoadFlowConfigMapper.class)); @BeforeEach void setUp() { + processConfigService = new ProcessConfigService( + processConfigRepository, + List.of(securityAnalysisConfigHandler, loadFlowConfigHandler) + ); + securityAnalysisConfig = new SecurityAnalysisConfig( UUID.randomUUID(), List.of(UUID.randomUUID()), @@ -100,7 +104,7 @@ void createSecurityAnalysisConfig() { @Test void getSecurityAnalysisConfig() { UUID processConfigId = UUID.randomUUID(); - SecurityAnalysisConfigEntity securityAnalysisConfigEntity = securityAnalysisConfigMapper.toEntity(securityAnalysisConfig); + SecurityAnalysisConfigEntity securityAnalysisConfigEntity = securityAnalysisConfigHandler.toEntity(securityAnalysisConfig); when(processConfigRepository.findById(processConfigId)).thenReturn(Optional.of(securityAnalysisConfigEntity)); @@ -126,9 +130,9 @@ void getSecurityAnalysisConfigsMetadata() { UUID processConfigId1 = UUID.randomUUID(); UUID processConfigId2 = UUID.randomUUID(); - SecurityAnalysisConfigEntity entity1 = securityAnalysisConfigMapper.toEntity(securityAnalysisConfig); + SecurityAnalysisConfigEntity entity1 = securityAnalysisConfigHandler.toEntity(securityAnalysisConfig); entity1.setId(processConfigId1); - SecurityAnalysisConfigEntity entity2 = securityAnalysisConfigMapper.toEntity(securityAnalysisConfig); + SecurityAnalysisConfigEntity entity2 = securityAnalysisConfigHandler.toEntity(securityAnalysisConfig); entity2.setId(processConfigId2); when(processConfigRepository.findAllById(List.of(processConfigId1, processConfigId2))) @@ -146,7 +150,7 @@ void getSecurityAnalysisConfigsMetadata() { @Test void updateSecurityAnalysisConfig() { UUID processConfigId = UUID.randomUUID(); - SecurityAnalysisConfigEntity securityAnalysisConfigEntity = securityAnalysisConfigMapper.toEntity(securityAnalysisConfig); + SecurityAnalysisConfigEntity securityAnalysisConfigEntity = securityAnalysisConfigHandler.toEntity(securityAnalysisConfig); SecurityAnalysisConfig newSecurityAnalysisConfig = new SecurityAnalysisConfig( UUID.randomUUID(), @@ -188,7 +192,7 @@ void duplicateSecurityAnalysisConfig() { UUID sourceProcessConfigId = UUID.randomUUID(); UUID expectedNewProcessConfigId = UUID.randomUUID(); - SecurityAnalysisConfigEntity sourceEntity = securityAnalysisConfigMapper.toEntity(securityAnalysisConfig); + SecurityAnalysisConfigEntity sourceEntity = securityAnalysisConfigHandler.toEntity(securityAnalysisConfig); sourceEntity.setId(sourceProcessConfigId); when(processConfigRepository.findById(sourceProcessConfigId)).thenReturn(Optional.of(sourceEntity)); @@ -254,9 +258,9 @@ void deleteProcessConfigNotFound() { @Test void getSecurityAnalysisConfigs() { SecurityAnalysisConfig securityAnalysisConfig1 = new SecurityAnalysisConfig(UUID.randomUUID(), List.of(UUID.randomUUID(), UUID.randomUUID()), UUID.randomUUID()); - SecurityAnalysisConfigEntity securityAnalysisConfigEntity1 = securityAnalysisConfigMapper.toEntity(securityAnalysisConfig1); + SecurityAnalysisConfigEntity securityAnalysisConfigEntity1 = securityAnalysisConfigHandler.toEntity(securityAnalysisConfig1); SecurityAnalysisConfig securityAnalysisConfig2 = new SecurityAnalysisConfig(UUID.randomUUID(), List.of(UUID.randomUUID()), UUID.randomUUID()); - SecurityAnalysisConfigEntity securityAnalysisConfigEntity2 = securityAnalysisConfigMapper.toEntity(securityAnalysisConfig2); + SecurityAnalysisConfigEntity securityAnalysisConfigEntity2 = securityAnalysisConfigHandler.toEntity(securityAnalysisConfig2); when(processConfigRepository.findAllByProcessType(ProcessType.SECURITY_ANALYSIS)) .thenReturn(List.of(securityAnalysisConfigEntity1, securityAnalysisConfigEntity2)); @@ -313,7 +317,7 @@ void createLoadFlowConfig() { @Test void getLoadFlowConfig() { UUID processConfigId = UUID.randomUUID(); - LoadFlowConfigEntity loadFlowConfigEntity = loadFlowConfigMapper.toEntity(loadFlowConfig); + LoadFlowConfigEntity loadFlowConfigEntity = loadFlowConfigHandler.toEntity(loadFlowConfig); when(processConfigRepository.findById(processConfigId)).thenReturn(Optional.of(loadFlowConfigEntity)); @@ -326,7 +330,7 @@ void getLoadFlowConfig() { @Test void updateLoadFlowConfig() { UUID processConfigId = UUID.randomUUID(); - LoadFlowConfigEntity loadFlowConfigEntity = loadFlowConfigMapper.toEntity(loadFlowConfig); + LoadFlowConfigEntity loadFlowConfigEntity = loadFlowConfigHandler.toEntity(loadFlowConfig); LoadFlowConfig newLoadFlowConfig = new LoadFlowConfig( UUID.randomUUID(), @@ -365,7 +369,7 @@ void updateLoadFlowConfigNotFound() { @Test void updateProcessConfigWithTypeMismatchShouldThrow() { UUID processConfigId = UUID.randomUUID(); - SecurityAnalysisConfigEntity entity = securityAnalysisConfigMapper.toEntity(securityAnalysisConfig); + SecurityAnalysisConfigEntity entity = securityAnalysisConfigHandler.toEntity(securityAnalysisConfig); when(processConfigRepository.findById(processConfigId)).thenReturn(Optional.of(entity)); @@ -378,7 +382,7 @@ void duplicateLoadFlowConfig() { UUID processConfigId = UUID.randomUUID(); UUID expectedNewProcessConfigId = UUID.randomUUID(); - LoadFlowConfigEntity sourceEntity = loadFlowConfigMapper.toEntity(loadFlowConfig); + LoadFlowConfigEntity sourceEntity = loadFlowConfigHandler.toEntity(loadFlowConfig); sourceEntity.setId(processConfigId); when(processConfigRepository.findById(processConfigId)).thenReturn(Optional.of(sourceEntity)); @@ -405,10 +409,10 @@ void duplicateLoadFlowConfig() { @Test void getLoadFlowConfigs() { LoadFlowConfig loadFlowConfig1 = new LoadFlowConfig(UUID.randomUUID(), List.of(UUID.randomUUID(), UUID.randomUUID())); - LoadFlowConfigEntity loadFlowConfigEntity1 = loadFlowConfigMapper.toEntity(loadFlowConfig1); + LoadFlowConfigEntity loadFlowConfigEntity1 = loadFlowConfigHandler.toEntity(loadFlowConfig1); LoadFlowConfig loadFlowConfig2 = new LoadFlowConfig(UUID.randomUUID(), List.of(UUID.randomUUID())); - LoadFlowConfigEntity loadFlowConfigEntity2 = loadFlowConfigMapper.toEntity(loadFlowConfig2); + LoadFlowConfigEntity loadFlowConfigEntity2 = loadFlowConfigHandler.toEntity(loadFlowConfig2); when(processConfigRepository.findAllByProcessType(ProcessType.LOADFLOW)) .thenReturn(List.of(loadFlowConfigEntity1, loadFlowConfigEntity2)); @@ -444,9 +448,9 @@ void getLoadFlowConfigsMetadata() { UUID processConfigId1 = UUID.randomUUID(); UUID processConfigId2 = UUID.randomUUID(); - LoadFlowConfigEntity entity1 = loadFlowConfigMapper.toEntity(loadFlowConfig); + LoadFlowConfigEntity entity1 = loadFlowConfigHandler.toEntity(loadFlowConfig); entity1.setId(processConfigId1); - LoadFlowConfigEntity entity2 = loadFlowConfigMapper.toEntity(loadFlowConfig); + LoadFlowConfigEntity entity2 = loadFlowConfigHandler.toEntity(loadFlowConfig); entity2.setId(processConfigId2); when(processConfigRepository.findAllById(List.of(processConfigId1, processConfigId2))) @@ -467,18 +471,16 @@ void compareProcessConfigsShouldReturnIdenticalWhenConfigsAreEqual() { UUID uuid2 = UUID.randomUUID(); SecurityAnalysisConfig config = new SecurityAnalysisConfig(UUID.randomUUID(), List.of(UUID.randomUUID(), UUID.randomUUID()), UUID.randomUUID()); - SecurityAnalysisConfigEntity entity1 = securityAnalysisConfigMapper.toEntity(config); + SecurityAnalysisConfigEntity entity1 = securityAnalysisConfigHandler.toEntity(config); entity1.setId(uuid1); - SecurityAnalysisConfigEntity entity2 = securityAnalysisConfigMapper.toEntity(config); + SecurityAnalysisConfigEntity entity2 = securityAnalysisConfigHandler.toEntity(config); entity2.setId(uuid2); when(processConfigRepository.findById(uuid1)).thenReturn(Optional.of(entity1)); when(processConfigRepository.findById(uuid2)).thenReturn(Optional.of(entity2)); - Optional result = processConfigService.compareProcessConfigs(uuid1, uuid2); + ProcessConfigComparison comparison = processConfigService.compareProcessConfigs(uuid1, uuid2); - assertThat(result).isPresent(); - ProcessConfigComparison comparison = result.get(); assertThat(comparison.processConfigUuid1()).isEqualTo(uuid1); assertThat(comparison.processConfigUuid2()).isEqualTo(uuid2); assertThat(comparison.identical()).isTrue(); @@ -495,20 +497,18 @@ void compareProcessConfigsShouldReturnDifferencesWhenModificationsAreDifferent() List modificationUuids1 = List.of(UUID.randomUUID(), UUID.randomUUID()); List modificationUuids2 = List.of(UUID.randomUUID(), UUID.randomUUID()); - SecurityAnalysisConfigEntity entity1 = securityAnalysisConfigMapper.toEntity( + SecurityAnalysisConfigEntity entity1 = securityAnalysisConfigHandler.toEntity( new SecurityAnalysisConfig(securityAnalysisParametersUuid, modificationUuids1, loadflowParametersUuid)); entity1.setId(uuid1); - SecurityAnalysisConfigEntity entity2 = securityAnalysisConfigMapper.toEntity( + SecurityAnalysisConfigEntity entity2 = securityAnalysisConfigHandler.toEntity( new SecurityAnalysisConfig(securityAnalysisParametersUuid, modificationUuids2, loadflowParametersUuid)); entity2.setId(uuid2); when(processConfigRepository.findById(uuid1)).thenReturn(Optional.of(entity1)); when(processConfigRepository.findById(uuid2)).thenReturn(Optional.of(entity2)); - Optional result = processConfigService.compareProcessConfigs(uuid1, uuid2); + ProcessConfigComparison comparison = processConfigService.compareProcessConfigs(uuid1, uuid2); - assertThat(result).isPresent(); - ProcessConfigComparison comparison = result.get(); assertThat(comparison.identical()).isFalse(); assertThat(comparison.differences()).hasSize(3); @@ -530,20 +530,18 @@ void compareProcessConfigsShouldReturnDifferencesWhenParametersAreDifferent() { UUID loadflowParametersUuid = UUID.randomUUID(); List modificationUuids = List.of(UUID.randomUUID()); - SecurityAnalysisConfigEntity entity1 = securityAnalysisConfigMapper.toEntity( + SecurityAnalysisConfigEntity entity1 = securityAnalysisConfigHandler.toEntity( new SecurityAnalysisConfig(securityAnalysisParametersUuid1, modificationUuids, loadflowParametersUuid)); entity1.setId(uuid1); - SecurityAnalysisConfigEntity entity2 = securityAnalysisConfigMapper.toEntity( + SecurityAnalysisConfigEntity entity2 = securityAnalysisConfigHandler.toEntity( new SecurityAnalysisConfig(securityAnalysisParametersUuid2, modificationUuids, loadflowParametersUuid)); entity2.setId(uuid2); when(processConfigRepository.findById(uuid1)).thenReturn(Optional.of(entity1)); when(processConfigRepository.findById(uuid2)).thenReturn(Optional.of(entity2)); - Optional result = processConfigService.compareProcessConfigs(uuid1, uuid2); + ProcessConfigComparison comparison = processConfigService.compareProcessConfigs(uuid1, uuid2); - assertThat(result).isPresent(); - ProcessConfigComparison comparison = result.get(); assertThat(comparison.identical()).isFalse(); ProcessConfigFieldComparison parametersComparison = comparison.differences().stream() @@ -566,20 +564,18 @@ void compareProcessConfigsShouldDetectOrderDifferenceInModifications() { List modificationUuids1 = List.of(mod1, mod2); List modificationUuids2 = List.of(mod2, mod1); // Different order - SecurityAnalysisConfigEntity entity1 = securityAnalysisConfigMapper.toEntity( + SecurityAnalysisConfigEntity entity1 = securityAnalysisConfigHandler.toEntity( new SecurityAnalysisConfig(securityAnalysisParametersUuid, modificationUuids1, loadflowParametersUuid)); entity1.setId(uuid1); - SecurityAnalysisConfigEntity entity2 = securityAnalysisConfigMapper.toEntity( + SecurityAnalysisConfigEntity entity2 = securityAnalysisConfigHandler.toEntity( new SecurityAnalysisConfig(securityAnalysisParametersUuid, modificationUuids2, loadflowParametersUuid)); entity2.setId(uuid2); when(processConfigRepository.findById(uuid1)).thenReturn(Optional.of(entity1)); when(processConfigRepository.findById(uuid2)).thenReturn(Optional.of(entity2)); - Optional result = processConfigService.compareProcessConfigs(uuid1, uuid2); + ProcessConfigComparison comparison = processConfigService.compareProcessConfigs(uuid1, uuid2); - assertThat(result).isPresent(); - ProcessConfigComparison comparison = result.get(); assertThat(comparison.identical()).isFalse(); ProcessConfigFieldComparison modificationsComparison = comparison.differences().stream() @@ -595,18 +591,16 @@ void compareLoadFlowConfigsShouldReturnIdenticalWhenConfigsAreEqual() { UUID uuid2 = UUID.randomUUID(); LoadFlowConfig config = new LoadFlowConfig(UUID.randomUUID(), List.of(UUID.randomUUID(), UUID.randomUUID())); - LoadFlowConfigEntity entity1 = loadFlowConfigMapper.toEntity(config); + LoadFlowConfigEntity entity1 = loadFlowConfigHandler.toEntity(config); entity1.setId(uuid1); - LoadFlowConfigEntity entity2 = loadFlowConfigMapper.toEntity(config); + LoadFlowConfigEntity entity2 = loadFlowConfigHandler.toEntity(config); entity2.setId(uuid2); when(processConfigRepository.findById(uuid1)).thenReturn(Optional.of(entity1)); when(processConfigRepository.findById(uuid2)).thenReturn(Optional.of(entity2)); - Optional result = processConfigService.compareProcessConfigs(uuid1, uuid2); + ProcessConfigComparison comparison = processConfigService.compareProcessConfigs(uuid1, uuid2); - assertThat(result).isPresent(); - ProcessConfigComparison comparison = result.get(); assertThat(comparison.processConfigUuid1()).isEqualTo(uuid1); assertThat(comparison.processConfigUuid2()).isEqualTo(uuid2); assertThat(comparison.identical()).isTrue(); @@ -622,18 +616,16 @@ void compareLoadFlowConfigsShouldReturnDifferencesWhenModificationsAreDifferent( List modificationUuids1 = List.of(UUID.randomUUID(), UUID.randomUUID()); List modificationUuids2 = List.of(UUID.randomUUID(), UUID.randomUUID()); - LoadFlowConfigEntity entity1 = loadFlowConfigMapper.toEntity(new LoadFlowConfig(loadflowParametersUuid, modificationUuids1)); + LoadFlowConfigEntity entity1 = loadFlowConfigHandler.toEntity(new LoadFlowConfig(loadflowParametersUuid, modificationUuids1)); entity1.setId(uuid1); - LoadFlowConfigEntity entity2 = loadFlowConfigMapper.toEntity(new LoadFlowConfig(loadflowParametersUuid, modificationUuids2)); + LoadFlowConfigEntity entity2 = loadFlowConfigHandler.toEntity(new LoadFlowConfig(loadflowParametersUuid, modificationUuids2)); entity2.setId(uuid2); when(processConfigRepository.findById(uuid1)).thenReturn(Optional.of(entity1)); when(processConfigRepository.findById(uuid2)).thenReturn(Optional.of(entity2)); - Optional result = processConfigService.compareProcessConfigs(uuid1, uuid2); + ProcessConfigComparison comparison = processConfigService.compareProcessConfigs(uuid1, uuid2); - assertThat(result).isPresent(); - ProcessConfigComparison comparison = result.get(); assertThat(comparison.identical()).isFalse(); assertThat(comparison.differences()).hasSize(2); @@ -654,18 +646,16 @@ void compareLoadFlowConfigsShouldReturnDifferencesWhenParametersAreDifferent() { UUID loadflowParametersUuid2 = UUID.randomUUID(); List modificationUuids = List.of(UUID.randomUUID()); - LoadFlowConfigEntity entity1 = loadFlowConfigMapper.toEntity(new LoadFlowConfig(loadflowParametersUuid1, modificationUuids)); + LoadFlowConfigEntity entity1 = loadFlowConfigHandler.toEntity(new LoadFlowConfig(loadflowParametersUuid1, modificationUuids)); entity1.setId(uuid1); - LoadFlowConfigEntity entity2 = loadFlowConfigMapper.toEntity(new LoadFlowConfig(loadflowParametersUuid2, modificationUuids)); + LoadFlowConfigEntity entity2 = loadFlowConfigHandler.toEntity(new LoadFlowConfig(loadflowParametersUuid2, modificationUuids)); entity2.setId(uuid2); when(processConfigRepository.findById(uuid1)).thenReturn(Optional.of(entity1)); when(processConfigRepository.findById(uuid2)).thenReturn(Optional.of(entity2)); - Optional result = processConfigService.compareProcessConfigs(uuid1, uuid2); + ProcessConfigComparison comparison = processConfigService.compareProcessConfigs(uuid1, uuid2); - assertThat(result).isPresent(); - ProcessConfigComparison comparison = result.get(); assertThat(comparison.identical()).isFalse(); ProcessConfigFieldComparison parametersComparison = comparison.differences().stream() @@ -682,13 +672,17 @@ void compareProcessConfigsShouldReturnEmptyWhenOneConfigNotFound() { UUID uuid1 = UUID.randomUUID(); UUID uuid2 = UUID.randomUUID(); - SecurityAnalysisConfigEntity entity2 = securityAnalysisConfigMapper.toEntity(securityAnalysisConfig); when(processConfigRepository.findById(uuid1)).thenReturn(Optional.empty()); - when(processConfigRepository.findById(uuid2)).thenReturn(Optional.of(entity2)); - Optional result = processConfigService.compareProcessConfigs(uuid1, uuid2); - - assertThat(result).isEmpty(); + assertThatThrownBy(() -> + processConfigService.compareProcessConfigs(uuid1, uuid2) + ) + .isInstanceOf(MonitorServerException.class) + .satisfies(ex -> { + MonitorServerException e = (MonitorServerException) ex; + assertEquals("Process config not found", e.getMessage()); + assertThat(e.getBusinessErrorValues()).containsEntry("processConfigUuid", uuid1); + }); } @Test @@ -696,9 +690,9 @@ void compareProcessConfigsShouldThrowWhenDifferentTypes() { UUID uuid1 = UUID.randomUUID(); UUID uuid2 = UUID.randomUUID(); - SecurityAnalysisConfigEntity entity1 = securityAnalysisConfigMapper.toEntity(securityAnalysisConfig); + SecurityAnalysisConfigEntity entity1 = securityAnalysisConfigHandler.toEntity(securityAnalysisConfig); entity1.setId(uuid1); - LoadFlowConfigEntity entity2 = loadFlowConfigMapper.toEntity(loadFlowConfig); + LoadFlowConfigEntity entity2 = loadFlowConfigHandler.toEntity(loadFlowConfig); entity2.setId(uuid2); when(processConfigRepository.findById(uuid1)).thenReturn(Optional.of(entity1)); @@ -709,4 +703,6 @@ void compareProcessConfigsShouldThrowWhenDifferentTypes() { assertThat(exception.getBusinessErrorValues()).containsEntry("processConfigEntity1Type", ProcessType.SECURITY_ANALYSIS); assertThat(exception.getBusinessErrorValues()).containsEntry("processConfigEntity2Type", ProcessType.LOADFLOW); } + + // TODO: @ParameterizedTest void getHandlerTest(ProcessType) } From 8defaed49d19b52d8845f62891d27e542c0fa62d Mon Sep 17 00:00:00 2001 From: Caroline Jeandat Date: Fri, 19 Jun 2026 13:51:01 +0200 Subject: [PATCH 2/9] review comments: remove business error PROCESS_CONFIG_NOT_FOUND Signed-off-by: Caroline Jeandat --- .../controllers/ProcessConfigController.java | 5 ++- .../error/MonitorServerBusinessErrorCode.java | 1 - .../error/MonitorServerExceptionHandler.java | 1 - .../processconfig/ProcessConfigService.java | 37 ++++++++++--------- .../ProcessConfigControllerTest.java | 9 ++--- .../MonitorServerExceptionHandlerTest.java | 2 - 6 files changed, 25 insertions(+), 30 deletions(-) diff --git a/monitor-server/src/main/java/org/gridsuite/monitor/server/controllers/ProcessConfigController.java b/monitor-server/src/main/java/org/gridsuite/monitor/server/controllers/ProcessConfigController.java index acad2ffe..e54f660a 100644 --- a/monitor-server/src/main/java/org/gridsuite/monitor/server/controllers/ProcessConfigController.java +++ b/monitor-server/src/main/java/org/gridsuite/monitor/server/controllers/ProcessConfigController.java @@ -18,6 +18,7 @@ import org.gridsuite.monitor.commons.types.processexecution.ProcessType; import org.gridsuite.monitor.server.dto.processconfig.ProcessConfigComparison; import org.gridsuite.monitor.server.services.processconfig.ProcessConfigService; +import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.DeleteMapping; @@ -133,7 +134,7 @@ public ResponseEntity compareProcessConfigs( @Parameter(description = "First process config UUID") @RequestParam("uuid1") UUID uuid1, @Parameter(description = "Second process config UUID") @RequestParam("uuid2") UUID uuid2) { - ProcessConfigComparison comparison = processConfigService.compareProcessConfigs(uuid1, uuid2); - return ResponseEntity.ok().body(comparison); + Optional comparison = processConfigService.compareProcessConfigs(uuid1, uuid2); + return comparison.map(c -> ResponseEntity.status(HttpStatus.OK).body(c)).orElseGet(() -> ResponseEntity.status(HttpStatus.NOT_FOUND).build()); } } diff --git a/monitor-server/src/main/java/org/gridsuite/monitor/server/error/MonitorServerBusinessErrorCode.java b/monitor-server/src/main/java/org/gridsuite/monitor/server/error/MonitorServerBusinessErrorCode.java index c6e72d5a..4315e801 100644 --- a/monitor-server/src/main/java/org/gridsuite/monitor/server/error/MonitorServerBusinessErrorCode.java +++ b/monitor-server/src/main/java/org/gridsuite/monitor/server/error/MonitorServerBusinessErrorCode.java @@ -12,7 +12,6 @@ * @author Franck Lecuyer */ public enum MonitorServerBusinessErrorCode implements BusinessErrorCode { - PROCESS_CONFIG_NOT_FOUND("monitor.server.processConfigNotFound"), DIFFERENT_PROCESS_CONFIG_TYPE("monitor.server.differentProcessConfigType"); private final String code; diff --git a/monitor-server/src/main/java/org/gridsuite/monitor/server/error/MonitorServerExceptionHandler.java b/monitor-server/src/main/java/org/gridsuite/monitor/server/error/MonitorServerExceptionHandler.java index 4713ef9d..05aa2258 100644 --- a/monitor-server/src/main/java/org/gridsuite/monitor/server/error/MonitorServerExceptionHandler.java +++ b/monitor-server/src/main/java/org/gridsuite/monitor/server/error/MonitorServerExceptionHandler.java @@ -35,7 +35,6 @@ protected MonitorServerBusinessErrorCode getBusinessCode(MonitorServerException @Override protected HttpStatus mapStatus(MonitorServerBusinessErrorCode errorCode) { return switch (errorCode) { - case PROCESS_CONFIG_NOT_FOUND -> HttpStatus.NOT_FOUND; case DIFFERENT_PROCESS_CONFIG_TYPE -> HttpStatus.BAD_REQUEST; }; } diff --git a/monitor-server/src/main/java/org/gridsuite/monitor/server/services/processconfig/ProcessConfigService.java b/monitor-server/src/main/java/org/gridsuite/monitor/server/services/processconfig/ProcessConfigService.java index 9332ca24..3f4db246 100644 --- a/monitor-server/src/main/java/org/gridsuite/monitor/server/services/processconfig/ProcessConfigService.java +++ b/monitor-server/src/main/java/org/gridsuite/monitor/server/services/processconfig/ProcessConfigService.java @@ -23,7 +23,6 @@ import java.util.stream.Collectors; import static org.gridsuite.monitor.server.error.MonitorServerBusinessErrorCode.DIFFERENT_PROCESS_CONFIG_TYPE; -import static org.gridsuite.monitor.server.error.MonitorServerBusinessErrorCode.PROCESS_CONFIG_NOT_FOUND; /** * @author Franck Lecuyer @@ -37,7 +36,9 @@ public ProcessConfigService(ProcessConfigRepository processConfigRepository, List> listHandlers) { this.processConfigRepository = processConfigRepository; this.processConfigHandlers = listHandlers.stream().collect(Collectors.toMap( - ProcessConfigHandler::getProcessType, Function.identity() + ProcessConfigHandler::getProcessType, Function.identity(), (h1, h2) -> { + throw new IllegalStateException(String.format("Duplicate process config handlers for process type: %s", h1.getProcessType())); + } )); } @@ -59,7 +60,7 @@ public UUID createProcessConfig(ProcessConfig processConfig) { @Transactional(readOnly = true) public Optional getProcessConfig(UUID processConfigUuid) { return processConfigRepository.findById(processConfigUuid) - .map(this::toPersistedProcessConfig); // TODO: renvoyer l'erreur not found ici au lieu de se trimbaler un Optional ? + .map(this::toPersistedProcessConfig); } @Transactional(readOnly = true) @@ -85,7 +86,7 @@ public Optional updateProcessConfig(UUID processConfigUuid, ProcessConfig } getHandler(processConfig.processType()).update(entity, processConfig); return processConfigUuid; - }); // TODO: renvoyer l'erreur not found ici au lieu de se trimbaler un Optional ? + }); } @Transactional @@ -94,7 +95,7 @@ public Optional duplicateProcessConfig(UUID sourceProcessConfigUuid) { .map(sourceEntity -> { ProcessConfigEntity entity = getHandler(sourceEntity.getProcessType()).copyEntity(sourceEntity); return processConfigRepository.save(entity).getId(); - }); // TODO: renvoyer l'erreur not found ici au lieu de se trimbaler un Optional ? + }); } @Transactional @@ -104,7 +105,7 @@ public Optional deleteProcessConfig(UUID processConfigUuid) { return Optional.of(processConfigUuid); } else { return Optional.empty(); - } // TODO: renvoyer l'erreur not found ici au lieu de se trimbaler un Optional ? + } } private PersistedProcessConfig toPersistedProcessConfig(ProcessConfigEntity entity) { @@ -113,22 +114,22 @@ private PersistedProcessConfig toPersistedProcessConfig(ProcessConfigEntity enti } @Transactional(readOnly = true) - public ProcessConfigComparison compareProcessConfigs(UUID uuid1, UUID uuid2) { - ProcessConfigEntity entity1 = processConfigRepository.findById(uuid1) - .orElseThrow(() -> new MonitorServerException(PROCESS_CONFIG_NOT_FOUND, "Process config not found", - Map.of("processConfigUuid", uuid1))); - ProcessConfigEntity entity2 = processConfigRepository.findById(uuid2) - .orElseThrow(() -> new MonitorServerException(PROCESS_CONFIG_NOT_FOUND, "Process config not found", - Map.of("processConfigUuid", uuid2))); - - if (entity1.getProcessType() != entity2.getProcessType()) { + public Optional compareProcessConfigs(UUID uuid1, UUID uuid2) { + Optional processConfigEntity1 = processConfigRepository.findById(uuid1); + Optional processConfigEntity2 = processConfigRepository.findById(uuid2); + + if (processConfigEntity1.isEmpty() || processConfigEntity2.isEmpty()) { + return Optional.empty(); + } + + if (processConfigEntity1.get().getProcessType() != processConfigEntity2.get().getProcessType()) { throw new MonitorServerException(DIFFERENT_PROCESS_CONFIG_TYPE, "Cannot compare different process config types", - Map.of("processConfigEntity1Type", entity1.getProcessType(), "processConfigEntity2Type", entity2.getProcessType())); + Map.of("processConfigEntity1Type", processConfigEntity1.get().getProcessType(), "processConfigEntity2Type", processConfigEntity2.get().getProcessType())); } - List differences = getHandler(entity1.getProcessType()).computeDifferences(entity1, entity2); + List differences = getHandler(processConfigEntity1.get().getProcessType()).computeDifferences(processConfigEntity1.get(), processConfigEntity2.get()); boolean identical = differences.stream().allMatch(ProcessConfigFieldComparison::identical); - return new ProcessConfigComparison(uuid1, uuid2, identical, differences); + return Optional.of(new ProcessConfigComparison(uuid1, uuid2, identical, differences)); } } diff --git a/monitor-server/src/test/java/org/gridsuite/monitor/server/controllers/ProcessConfigControllerTest.java b/monitor-server/src/test/java/org/gridsuite/monitor/server/controllers/ProcessConfigControllerTest.java index 73060c48..f67a9da2 100644 --- a/monitor-server/src/test/java/org/gridsuite/monitor/server/controllers/ProcessConfigControllerTest.java +++ b/monitor-server/src/test/java/org/gridsuite/monitor/server/controllers/ProcessConfigControllerTest.java @@ -25,12 +25,10 @@ import org.springframework.test.web.servlet.MockMvc; import java.util.List; -import java.util.Map; import java.util.Optional; import java.util.UUID; import static org.gridsuite.monitor.server.error.MonitorServerBusinessErrorCode.DIFFERENT_PROCESS_CONFIG_TYPE; -import static org.gridsuite.monitor.server.error.MonitorServerBusinessErrorCode.PROCESS_CONFIG_NOT_FOUND; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -274,7 +272,7 @@ void compareProcessConfigsShouldReturnComparisonResult() throws Exception { ); when(processConfigService.compareProcessConfigs(uuid1, uuid2)) - .thenReturn(comparison); + .thenReturn(Optional.of(comparison)); mockMvc.perform(get("/v1/process-configs/compare") .param("uuid1", uuid1.toString()) @@ -309,7 +307,7 @@ void compareProcessConfigsShouldReturnDifferences() throws Exception { // TODO: ); when(processConfigService.compareProcessConfigs(uuid1, uuid2)) - .thenReturn(comparison); + .thenReturn(Optional.of(comparison)); mockMvc.perform(get("/v1/process-configs/compare") .param("uuid1", uuid1.toString()) @@ -330,8 +328,7 @@ void compareProcessConfigsShouldReturn404WhenConfigNotFound() throws Exception { UUID uuid2 = UUID.randomUUID(); when(processConfigService.compareProcessConfigs(uuid1, uuid2)) - .thenThrow(new MonitorServerException(PROCESS_CONFIG_NOT_FOUND, "Process config not found", - Map.of("processConfigUuid", uuid1))); + .thenReturn(Optional.empty()); mockMvc.perform(get("/v1/process-configs/compare") .param("uuid1", uuid1.toString()) diff --git a/monitor-server/src/test/java/org/gridsuite/monitor/server/error/MonitorServerExceptionHandlerTest.java b/monitor-server/src/test/java/org/gridsuite/monitor/server/error/MonitorServerExceptionHandlerTest.java index 07663c43..d507307c 100644 --- a/monitor-server/src/test/java/org/gridsuite/monitor/server/error/MonitorServerExceptionHandlerTest.java +++ b/monitor-server/src/test/java/org/gridsuite/monitor/server/error/MonitorServerExceptionHandlerTest.java @@ -38,6 +38,4 @@ void mapsBadRequestBusinessErrorToStatus() { assertThat(response.getBody()).isNotNull(); assertEquals("monitor.server.differentProcessConfigType", response.getBody().getBusinessErrorCode()); } - - // TODO: test PROCESS_CONFIG_NOT_FOUND } From 752ca973b9fd5fd1e7bc0535172f464219eb6066 Mon Sep 17 00:00:00 2001 From: Caroline Jeandat Date: Mon, 22 Jun 2026 17:52:09 +0200 Subject: [PATCH 3/9] add tests Signed-off-by: Caroline Jeandat --- .../AbstractProcessConfigHandler.java | 33 +- .../processconfig/LoadFlowConfigHandler.java | 25 +- .../processconfig/ProcessConfigHandler.java | 2 +- .../processconfig/ProcessConfigService.java | 2 +- .../SecurityAnalysisConfigHandler.java | 33 +- .../ProcessConfigControllerTest.java | 4 +- .../AbstractProcessConfigMapperTest.java | 19 - .../AbstractProcessConfigHandlerTest.java | 98 +++ .../LoadFlowConfigHandlerTest.java | 162 ++++ .../ProcessConfigHandlerTest.java | 26 - .../ProcessConfigServiceTest.java | 792 +++++------------- .../SecurityAnalysisConfigHandlerTest.java | 194 +++++ 12 files changed, 734 insertions(+), 656 deletions(-) delete mode 100644 monitor-server/src/test/java/org/gridsuite/monitor/server/mappers/processconfig/AbstractProcessConfigMapperTest.java create mode 100644 monitor-server/src/test/java/org/gridsuite/monitor/server/services/processconfig/AbstractProcessConfigHandlerTest.java create mode 100644 monitor-server/src/test/java/org/gridsuite/monitor/server/services/processconfig/LoadFlowConfigHandlerTest.java delete mode 100644 monitor-server/src/test/java/org/gridsuite/monitor/server/services/processconfig/ProcessConfigHandlerTest.java create mode 100644 monitor-server/src/test/java/org/gridsuite/monitor/server/services/processconfig/SecurityAnalysisConfigHandlerTest.java diff --git a/monitor-server/src/main/java/org/gridsuite/monitor/server/services/processconfig/AbstractProcessConfigHandler.java b/monitor-server/src/main/java/org/gridsuite/monitor/server/services/processconfig/AbstractProcessConfigHandler.java index f69da8b2..7fa5f7d8 100644 --- a/monitor-server/src/main/java/org/gridsuite/monitor/server/services/processconfig/AbstractProcessConfigHandler.java +++ b/monitor-server/src/main/java/org/gridsuite/monitor/server/services/processconfig/AbstractProcessConfigHandler.java @@ -7,14 +7,9 @@ package org.gridsuite.monitor.server.services.processconfig; import org.gridsuite.monitor.commons.types.processconfig.ProcessConfig; -import org.gridsuite.monitor.server.dto.processconfig.ProcessConfigFieldComparison; import org.gridsuite.monitor.server.entities.processconfig.ProcessConfigEntity; import org.gridsuite.monitor.server.mappers.processconfig.ProcessConfigMapper; -import java.util.ArrayList; -import java.util.List; -import java.util.Objects; - /** * @author Caroline Jeandat {@literal } */ @@ -28,7 +23,7 @@ protected AbstractProcessConfigHandler(M mapper) { } @Override - public void update(E entity, C processConfig) { + public void update(C processConfig, E entity) { mapper.updateEntityFromDto(processConfig, entity); } @@ -46,30 +41,4 @@ public E toEntity(C processConfig) { public C toProcessConfig(E entity) { return mapper.toDto(entity); } - - @Override - public List computeDifferences(E entity1, E entity2) { - C config1 = toProcessConfig(entity1); - C config2 = toProcessConfig(entity2); - List differences = new ArrayList<>(); - - // Compare modifications - addFieldComparison(config1.modificationUuids(), config2.modificationUuids(), differences, "modifications"); - - // Compare other fields - addProcessConfigSpecificFieldsComparison(config1, config2, differences); - - return differences; - } - - protected abstract void addProcessConfigSpecificFieldsComparison(C config1, C config2, List differences); - - protected void addFieldComparison(Object value1, Object value2, List differences, String fieldName) { - differences.add(new ProcessConfigFieldComparison( - fieldName, - Objects.equals(value1, value2), - value1, - value2 - )); - } } diff --git a/monitor-server/src/main/java/org/gridsuite/monitor/server/services/processconfig/LoadFlowConfigHandler.java b/monitor-server/src/main/java/org/gridsuite/monitor/server/services/processconfig/LoadFlowConfigHandler.java index 6cb4be5f..b6c5f948 100644 --- a/monitor-server/src/main/java/org/gridsuite/monitor/server/services/processconfig/LoadFlowConfigHandler.java +++ b/monitor-server/src/main/java/org/gridsuite/monitor/server/services/processconfig/LoadFlowConfigHandler.java @@ -13,7 +13,9 @@ import org.gridsuite.monitor.server.mappers.processconfig.LoadFlowConfigMapper; import org.springframework.stereotype.Service; +import java.util.ArrayList; import java.util.List; +import java.util.Objects; /** * @author Caroline Jeandat {@literal } @@ -31,8 +33,27 @@ public ProcessType getProcessType() { } @Override - protected void addProcessConfigSpecificFieldsComparison(LoadFlowConfig config1, LoadFlowConfig config2, List differences) { + public List computeDifferences(LoadFlowConfigEntity entity1, LoadFlowConfigEntity entity2) { + LoadFlowConfig config1 = toProcessConfig(entity1); + LoadFlowConfig config2 = toProcessConfig(entity2); + List differences = new ArrayList<>(); + + // Compare modifications + differences.add(new ProcessConfigFieldComparison( + "modifications", + Objects.equals(config1.modificationUuids(), config2.modificationUuids()), + config1.modificationUuids(), + config2.modificationUuids() + )); + // Compare loadflow parameters - addFieldComparison(config1.loadflowParametersUuid(), config2.loadflowParametersUuid(), differences, "loadflowParameters"); + differences.add(new ProcessConfigFieldComparison( + "loadflowParameters", + Objects.equals(config1.loadflowParametersUuid(), config2.loadflowParametersUuid()), + config1.loadflowParametersUuid(), + config2.loadflowParametersUuid() + )); + + return differences; } } diff --git a/monitor-server/src/main/java/org/gridsuite/monitor/server/services/processconfig/ProcessConfigHandler.java b/monitor-server/src/main/java/org/gridsuite/monitor/server/services/processconfig/ProcessConfigHandler.java index 38e3ae23..34fe58db 100644 --- a/monitor-server/src/main/java/org/gridsuite/monitor/server/services/processconfig/ProcessConfigHandler.java +++ b/monitor-server/src/main/java/org/gridsuite/monitor/server/services/processconfig/ProcessConfigHandler.java @@ -20,7 +20,7 @@ public interface ProcessConfigHandler updateProcessConfig(UUID processConfigUuid, ProcessConfig if (entity.getProcessType() != processConfig.processType()) { throw new IllegalArgumentException("Process config type mismatch : " + entity.getProcessType()); } - getHandler(processConfig.processType()).update(entity, processConfig); + getHandler(processConfig.processType()).update(processConfig, entity); return processConfigUuid; }); } diff --git a/monitor-server/src/main/java/org/gridsuite/monitor/server/services/processconfig/SecurityAnalysisConfigHandler.java b/monitor-server/src/main/java/org/gridsuite/monitor/server/services/processconfig/SecurityAnalysisConfigHandler.java index 5049a726..5bfb0107 100644 --- a/monitor-server/src/main/java/org/gridsuite/monitor/server/services/processconfig/SecurityAnalysisConfigHandler.java +++ b/monitor-server/src/main/java/org/gridsuite/monitor/server/services/processconfig/SecurityAnalysisConfigHandler.java @@ -13,7 +13,9 @@ import org.gridsuite.monitor.server.mappers.processconfig.SecurityAnalysisConfigMapper; import org.springframework.stereotype.Service; +import java.util.ArrayList; import java.util.List; +import java.util.Objects; /** * @author Caroline Jeandat {@literal } @@ -31,11 +33,36 @@ public ProcessType getProcessType() { } @Override - protected void addProcessConfigSpecificFieldsComparison(SecurityAnalysisConfig config1, SecurityAnalysisConfig config2, List differences) { + public List computeDifferences(SecurityAnalysisConfigEntity entity1, SecurityAnalysisConfigEntity entity2) { + // error si pas bon processType + SecurityAnalysisConfig config1 = toProcessConfig(entity1); + SecurityAnalysisConfig config2 = toProcessConfig(entity2); + List differences = new ArrayList<>(); + + // Compare modifications + differences.add(new ProcessConfigFieldComparison( + "modifications", + Objects.equals(config1.modificationUuids(), config2.modificationUuids()), + config1.modificationUuids(), + config2.modificationUuids() + )); + // Compare loadflow parameters - addFieldComparison(config1.loadflowParametersUuid(), config2.loadflowParametersUuid(), differences, "loadflowParameters"); + differences.add(new ProcessConfigFieldComparison( + "loadflowParameters", + Objects.equals(config1.loadflowParametersUuid(), config2.loadflowParametersUuid()), + config1.loadflowParametersUuid(), + config2.loadflowParametersUuid() + )); // Compare security analysis parameters - addFieldComparison(config1.securityAnalysisParametersUuid(), config2.securityAnalysisParametersUuid(), differences, "securityAnalysisParameters"); + differences.add(new ProcessConfigFieldComparison( + "securityAnalysisParameters", + Objects.equals(config1.securityAnalysisParametersUuid(), config2.securityAnalysisParametersUuid()), + config1.securityAnalysisParametersUuid(), + config2.securityAnalysisParametersUuid() + )); + + return differences; } } diff --git a/monitor-server/src/test/java/org/gridsuite/monitor/server/controllers/ProcessConfigControllerTest.java b/monitor-server/src/test/java/org/gridsuite/monitor/server/controllers/ProcessConfigControllerTest.java index f67a9da2..848f320e 100644 --- a/monitor-server/src/test/java/org/gridsuite/monitor/server/controllers/ProcessConfigControllerTest.java +++ b/monitor-server/src/test/java/org/gridsuite/monitor/server/controllers/ProcessConfigControllerTest.java @@ -285,13 +285,12 @@ void compareProcessConfigsShouldReturnComparisonResult() throws Exception { .andExpect(jsonPath("$.identical").value(true)) .andExpect(jsonPath("$.differences").isArray()) .andExpect(jsonPath("$.differences.length()").value(3)); - // TODO: remplacer les jsonPath par la récupération du MvcResult et égalité avec l'objet de référence verify(processConfigService).compareProcessConfigs(uuid1, uuid2); } @Test - void compareProcessConfigsShouldReturnDifferences() throws Exception { // TODO: quelle différence avec le test d'avant ? + void compareProcessConfigsShouldReturnDifferences() throws Exception { UUID uuid1 = UUID.randomUUID(); UUID uuid2 = UUID.randomUUID(); List modificationUuids1 = List.of(UUID.randomUUID()); @@ -317,7 +316,6 @@ void compareProcessConfigsShouldReturnDifferences() throws Exception { // TODO: .andExpect(jsonPath("$.identical").value(false)) .andExpect(jsonPath("$.differences[0].field").value("modifications")) .andExpect(jsonPath("$.differences[0].identical").value(false)); - // TODO: remplacer les jsonPath par la récupération du MvcResult et égalité avec l'objet de référence verify(processConfigService).compareProcessConfigs(uuid1, uuid2); } diff --git a/monitor-server/src/test/java/org/gridsuite/monitor/server/mappers/processconfig/AbstractProcessConfigMapperTest.java b/monitor-server/src/test/java/org/gridsuite/monitor/server/mappers/processconfig/AbstractProcessConfigMapperTest.java deleted file mode 100644 index da3a156d..00000000 --- a/monitor-server/src/test/java/org/gridsuite/monitor/server/mappers/processconfig/AbstractProcessConfigMapperTest.java +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright (c) 2026, RTE (http://www.rte-france.com) - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - */ -package org.gridsuite.monitor.server.mappers.processconfig; - -/** - * @author Caroline Jeandat {@literal } - */ -public abstract class AbstractProcessConfigMapperTest { - // TODO - // E toEntity(C dto); - - // C toDto(E entity); - - // void updateEntityFromDto(C dto, E entity); -} diff --git a/monitor-server/src/test/java/org/gridsuite/monitor/server/services/processconfig/AbstractProcessConfigHandlerTest.java b/monitor-server/src/test/java/org/gridsuite/monitor/server/services/processconfig/AbstractProcessConfigHandlerTest.java new file mode 100644 index 00000000..ef87fcbd --- /dev/null +++ b/monitor-server/src/test/java/org/gridsuite/monitor/server/services/processconfig/AbstractProcessConfigHandlerTest.java @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2026, RTE (http://www.rte-france.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ +package org.gridsuite.monitor.server.services.processconfig; + +import org.gridsuite.monitor.commons.types.processconfig.ProcessConfig; +import org.gridsuite.monitor.commons.types.processexecution.ProcessType; +import org.gridsuite.monitor.server.entities.processconfig.ProcessConfigEntity; +import org.gridsuite.monitor.server.mappers.processconfig.ProcessConfigMapper; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.*; + +/** + * @author Caroline Jeandat {@literal } + */ +public abstract class AbstractProcessConfigHandlerTest< + C extends ProcessConfig, + E extends ProcessConfigEntity, + M extends ProcessConfigMapper, + H extends ProcessConfigHandler> { + + protected M mapper; + + protected H handler; + + abstract ProcessType getProcessType(); + + abstract C createProcessConfig(); + + abstract E createProcessConfigEntity(); + + @BeforeEach + protected abstract void setUp(); + + @Test + void getProcessTypeTest() { + assertThat(handler.getProcessType()).isEqualTo(getProcessType()); + } + + @Test + void updateTest() { + E processConfigEntity = createProcessConfigEntity(); + C processConfig = createProcessConfig(); + + handler.update(processConfig, processConfigEntity); + + verify(mapper).updateEntityFromDto(processConfig, processConfigEntity); + } + + @Test + void copyEntityTest() { + E processConfigEntity1 = createProcessConfigEntity(); + E expectedProcessConfigEntity = createProcessConfigEntity(); + C processConfig = createProcessConfig(); + + when(mapper.toDto(processConfigEntity1)).thenReturn(processConfig); + when(mapper.toEntity(processConfig)).thenReturn(expectedProcessConfigEntity); + + ProcessConfigEntity result = handler.copyEntity(processConfigEntity1); + + assertThat(result).isEqualTo(expectedProcessConfigEntity); + verify(mapper).toDto(processConfigEntity1); + verify(mapper).toEntity(any()); + } + + @Test + void toEntityTest() { + E expectedProcessConfigEntity = createProcessConfigEntity(); + C processConfig = createProcessConfig(); + + when(mapper.toEntity(processConfig)).thenReturn(expectedProcessConfigEntity); + + ProcessConfigEntity result = handler.toEntity(processConfig); + + assertThat(result).isEqualTo(expectedProcessConfigEntity); + verify(mapper).toEntity(processConfig); + } + + @Test + void toProcessConfigTest() { + E processConfigEntity = createProcessConfigEntity(); + C expectedProcessConfig = createProcessConfig(); + + when(mapper.toDto(processConfigEntity)).thenReturn(expectedProcessConfig); + + ProcessConfig result = handler.toProcessConfig(processConfigEntity); + + assertThat(result).isEqualTo(expectedProcessConfig); + verify(mapper).toDto(processConfigEntity); + } +} diff --git a/monitor-server/src/test/java/org/gridsuite/monitor/server/services/processconfig/LoadFlowConfigHandlerTest.java b/monitor-server/src/test/java/org/gridsuite/monitor/server/services/processconfig/LoadFlowConfigHandlerTest.java new file mode 100644 index 00000000..60075b6b --- /dev/null +++ b/monitor-server/src/test/java/org/gridsuite/monitor/server/services/processconfig/LoadFlowConfigHandlerTest.java @@ -0,0 +1,162 @@ +/* + * Copyright (c) 2026, RTE (http://www.rte-france.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ +package org.gridsuite.monitor.server.services.processconfig; + +import org.gridsuite.monitor.commons.types.processconfig.LoadFlowConfig; + +import org.gridsuite.monitor.commons.types.processexecution.ProcessType; +import org.gridsuite.monitor.server.dto.processconfig.ProcessConfigFieldComparison; +import org.gridsuite.monitor.server.entities.processconfig.LoadFlowConfigEntity; +import org.gridsuite.monitor.server.mappers.processconfig.LoadFlowConfigMapper; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mapstruct.factory.Mappers; +import org.mockito.Mockito; +import org.mockito.junit.jupiter.MockitoExtension; + +import java.util.List; +import java.util.UUID; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +/** + * @author Caroline Jeandat {@literal } + */ +@ExtendWith(MockitoExtension.class) +class LoadFlowConfigHandlerTest extends AbstractProcessConfigHandlerTest { + @Override + ProcessType getProcessType() { + return ProcessType.LOADFLOW; + } + + @Override + LoadFlowConfig createProcessConfig() { + return new LoadFlowConfig(UUID.randomUUID(), List.of(UUID.randomUUID())); + } + + @Override + LoadFlowConfigEntity createProcessConfigEntity() { + return new LoadFlowConfigEntity(); + } + + @Override + @BeforeEach + protected void setUp() { + LoadFlowConfigMapper realMapper = Mappers.getMapper(LoadFlowConfigMapper.class); + mapper = Mockito.spy(realMapper); + handler = new LoadFlowConfigHandler(mapper); + } + + @Test + void computeDifferencesShouldReturnNoDifferenceWhenConfigsAreEqual() { + LoadFlowConfig processConfig = createProcessConfig(); + LoadFlowConfigEntity entity1 = createProcessConfigEntity(); + LoadFlowConfigEntity entity2 = createProcessConfigEntity(); + + when(mapper.toDto(entity1)).thenReturn(processConfig); + when(mapper.toDto(entity2)).thenReturn(processConfig); + + List result = handler.computeDifferences(entity1, entity2); + + assertThat(result) + .hasSize(2) + .allMatch(ProcessConfigFieldComparison::identical) + .allMatch(fieldComparison -> fieldComparison.value1().equals(fieldComparison.value2())); + } + + @Test + void computeDifferencesShouldReturnDifferentModificationsWhenModificationsAreDifferent() { + UUID loadflowParametersUuid = UUID.randomUUID(); + List modificationUuids1 = List.of(UUID.randomUUID(), UUID.randomUUID()); + List modificationUuids2 = List.of(UUID.randomUUID(), UUID.randomUUID()); + + LoadFlowConfig processConfig1 = new LoadFlowConfig(loadflowParametersUuid, modificationUuids1); + LoadFlowConfig processConfig2 = new LoadFlowConfig(loadflowParametersUuid, modificationUuids2); + + LoadFlowConfigEntity entity1 = Mockito.mock(LoadFlowConfigEntity.class); + LoadFlowConfigEntity entity2 = Mockito.mock(LoadFlowConfigEntity.class); + + when(mapper.toDto(entity1)).thenReturn(processConfig1); + when(mapper.toDto(entity2)).thenReturn(processConfig2); + + List result = handler.computeDifferences(entity1, entity2); + + assertThat(result).hasSize(2); + ProcessConfigFieldComparison comparison = result.stream() + .filter(d -> "modifications".equals(d.field())) + .findFirst() + .orElseThrow(); + assertThat(comparison.identical()).isFalse(); + assertThat(comparison.value1()).isEqualTo(modificationUuids1); + assertThat(comparison.value2()).isEqualTo(modificationUuids2); + verify(mapper).toDto(entity1); + verify(mapper).toDto(entity2); + } + + @Test + void computeDifferencesShouldDetectOrderDifferenceInModifications() { + UUID loadflowParametersUuid = UUID.randomUUID(); + UUID mod1 = UUID.randomUUID(); + UUID mod2 = UUID.randomUUID(); + List modificationUuids1 = List.of(mod1, mod2); + List modificationUuids2 = List.of(mod2, mod1); // Different order + + LoadFlowConfig processConfig1 = new LoadFlowConfig(loadflowParametersUuid, modificationUuids1); + LoadFlowConfig processConfig2 = new LoadFlowConfig(loadflowParametersUuid, modificationUuids2); + + LoadFlowConfigEntity entity1 = Mockito.mock(LoadFlowConfigEntity.class); + LoadFlowConfigEntity entity2 = Mockito.mock(LoadFlowConfigEntity.class); + + when(mapper.toDto(entity1)).thenReturn(processConfig1); + when(mapper.toDto(entity2)).thenReturn(processConfig2); + + List result = handler.computeDifferences(entity1, entity2); + + assertThat(result).hasSize(2); + ProcessConfigFieldComparison comparison = result.stream() + .filter(d -> "modifications".equals(d.field())) + .findFirst() + .orElseThrow(); + assertThat(comparison.identical()).isFalse(); + assertThat(comparison.value1()).isEqualTo(modificationUuids1); + assertThat(comparison.value2()).isEqualTo(modificationUuids2); + verify(mapper).toDto(entity1); + verify(mapper).toDto(entity2); + } + + @Test + void computeDifferencesShouldReturnDifferencesWhenParametersAreDifferent() { + UUID loadflowParametersUuid1 = UUID.randomUUID(); + UUID loadflowParametersUuid2 = UUID.randomUUID(); + List modificationUuids = List.of(UUID.randomUUID(), UUID.randomUUID()); + + LoadFlowConfig processConfig1 = new LoadFlowConfig(loadflowParametersUuid1, modificationUuids); + LoadFlowConfig processConfig2 = new LoadFlowConfig(loadflowParametersUuid2, modificationUuids); + + LoadFlowConfigEntity entity1 = Mockito.mock(LoadFlowConfigEntity.class); + LoadFlowConfigEntity entity2 = Mockito.mock(LoadFlowConfigEntity.class); + + when(mapper.toDto(entity1)).thenReturn(processConfig1); + when(mapper.toDto(entity2)).thenReturn(processConfig2); + + List result = handler.computeDifferences(entity1, entity2); + + assertThat(result).hasSize(2); + ProcessConfigFieldComparison comparison = result.stream() + .filter(d -> "loadflowParameters".equals(d.field())) + .findFirst() + .orElseThrow(); + assertThat(comparison.identical()).isFalse(); + assertThat(comparison.value1()).isEqualTo(loadflowParametersUuid1); + assertThat(comparison.value2()).isEqualTo(loadflowParametersUuid2); + verify(mapper).toDto(entity1); + verify(mapper).toDto(entity2); + } +} diff --git a/monitor-server/src/test/java/org/gridsuite/monitor/server/services/processconfig/ProcessConfigHandlerTest.java b/monitor-server/src/test/java/org/gridsuite/monitor/server/services/processconfig/ProcessConfigHandlerTest.java deleted file mode 100644 index 4c9fc035..00000000 --- a/monitor-server/src/test/java/org/gridsuite/monitor/server/services/processconfig/ProcessConfigHandlerTest.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright (c) 2026, RTE (http://www.rte-france.com) - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - */ -package org.gridsuite.monitor.server.services.processconfig; - -/** - * @author Caroline Jeandat {@literal } - */ -public class ProcessConfigHandlerTest { - // TODO, with parameterized tests sauf pour computeDifferences (seul qui est vraiment différent) - - // ProcessType getProcessType(); - - // void update(E entity, C processConfig); - - // E copyEntity(E sourceEntity); - - // E toEntity(C processConfig); - - // C toProcessConfig(E entity); - - // List computeDifferences(E entity1, E entity2); -} diff --git a/monitor-server/src/test/java/org/gridsuite/monitor/server/services/processconfig/ProcessConfigServiceTest.java b/monitor-server/src/test/java/org/gridsuite/monitor/server/services/processconfig/ProcessConfigServiceTest.java index d0ebb9d1..2c09eab9 100644 --- a/monitor-server/src/test/java/org/gridsuite/monitor/server/services/processconfig/ProcessConfigServiceTest.java +++ b/monitor-server/src/test/java/org/gridsuite/monitor/server/services/processconfig/ProcessConfigServiceTest.java @@ -6,37 +6,28 @@ */ package org.gridsuite.monitor.server.services.processconfig; -import org.gridsuite.monitor.commons.types.processconfig.LoadFlowConfig; +import org.gridsuite.monitor.commons.types.processconfig.ProcessConfig; +import org.gridsuite.monitor.commons.types.processexecution.ProcessType; import org.gridsuite.monitor.server.dto.processconfig.MetadataInfos; import org.gridsuite.monitor.server.dto.processconfig.PersistedProcessConfig; -import org.gridsuite.monitor.commons.types.processconfig.SecurityAnalysisConfig; -import org.gridsuite.monitor.commons.types.processexecution.ProcessType; import org.gridsuite.monitor.server.dto.processconfig.ProcessConfigComparison; import org.gridsuite.monitor.server.dto.processconfig.ProcessConfigFieldComparison; -import org.gridsuite.monitor.server.entities.processconfig.SecurityAnalysisConfigEntity; import org.gridsuite.monitor.server.entities.processconfig.LoadFlowConfigEntity; +import org.gridsuite.monitor.server.entities.processconfig.ProcessConfigEntity; +import org.gridsuite.monitor.server.entities.processconfig.SecurityAnalysisConfigEntity; import org.gridsuite.monitor.server.error.MonitorServerException; -import org.gridsuite.monitor.server.mappers.processconfig.LoadFlowConfigMapper; -import org.gridsuite.monitor.server.mappers.processconfig.SecurityAnalysisConfigMapper; import org.gridsuite.monitor.server.repositories.ProcessConfigRepository; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; -import org.mapstruct.factory.Mappers; -import org.mockito.ArgumentCaptor; import org.mockito.Mock; -import org.mockito.Spy; +import org.mockito.Mockito; import org.mockito.junit.jupiter.MockitoExtension; -import java.util.List; -import java.util.Optional; -import java.util.UUID; +import java.util.*; -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.assertj.core.api.AssertionsForClassTypes.catchThrowable; +import static org.assertj.core.api.Assertions.*; import static org.gridsuite.monitor.server.error.MonitorServerBusinessErrorCode.DIFFERENT_PROCESS_CONFIG_TYPE; -import static org.junit.jupiter.api.Assertions.assertEquals; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.*; @@ -48,661 +39,324 @@ class ProcessConfigServiceTest { @Mock private ProcessConfigRepository processConfigRepository; - private ProcessConfigService processConfigService; - - private SecurityAnalysisConfig securityAnalysisConfig; - private LoadFlowConfig loadFlowConfig; + @Mock + private ProcessConfigHandler handler; - @Spy - private final SecurityAnalysisConfigHandler securityAnalysisConfigHandler = new SecurityAnalysisConfigHandler(Mappers.getMapper(SecurityAnalysisConfigMapper.class)); + private ProcessConfigService processConfigService; - @Spy - private final LoadFlowConfigHandler loadFlowConfigHandler = new LoadFlowConfigHandler(Mappers.getMapper(LoadFlowConfigMapper.class)); + private static final ProcessType PROCESS_TYPE = ProcessType.SECURITY_ANALYSIS; + @Mock + private ProcessConfig processConfig; + @Mock + private ProcessConfigEntity processConfigEntity; @BeforeEach void setUp() { + when(handler.getProcessType()).thenReturn(PROCESS_TYPE); + processConfigService = new ProcessConfigService( processConfigRepository, - List.of(securityAnalysisConfigHandler, loadFlowConfigHandler) - ); - - securityAnalysisConfig = new SecurityAnalysisConfig( - UUID.randomUUID(), - List.of(UUID.randomUUID()), - UUID.randomUUID() - ); - loadFlowConfig = new LoadFlowConfig( - UUID.randomUUID(), - List.of(UUID.randomUUID()) + List.of(handler) ); } @Test - void createSecurityAnalysisConfig() { - UUID expectedProcessConfigId = UUID.randomUUID(); - when(processConfigRepository.save(any(SecurityAnalysisConfigEntity.class))) - .thenAnswer(invocation -> { - SecurityAnalysisConfigEntity entity = invocation.getArgument(0); - entity.setId(expectedProcessConfigId); - return entity; - }); - - UUID result = processConfigService.createProcessConfig(securityAnalysisConfig); - assertThat(result).isEqualTo(expectedProcessConfigId); - - ArgumentCaptor captor = ArgumentCaptor.forClass(SecurityAnalysisConfigEntity.class); - verify(processConfigRepository).save(captor.capture()); - - SecurityAnalysisConfigEntity savedEntity = captor.getValue(); - assertThat(savedEntity.getId()).isEqualTo(expectedProcessConfigId); - assertThat(savedEntity.getProcessType()).isEqualTo(ProcessType.SECURITY_ANALYSIS); - assertThat(savedEntity.getSecurityAnalysisParametersUuid()).isEqualTo(securityAnalysisConfig.securityAnalysisParametersUuid()); - assertThat(savedEntity.getLoadflowParametersUuid()).isEqualTo(securityAnalysisConfig.loadflowParametersUuid()); - assertThat(savedEntity.getModificationUuids()).isEqualTo(securityAnalysisConfig.modificationUuids()); - } - - @Test - void getSecurityAnalysisConfig() { - UUID processConfigId = UUID.randomUUID(); - SecurityAnalysisConfigEntity securityAnalysisConfigEntity = securityAnalysisConfigHandler.toEntity(securityAnalysisConfig); - - when(processConfigRepository.findById(processConfigId)).thenReturn(Optional.of(securityAnalysisConfigEntity)); - - Optional processConfig = processConfigService.getProcessConfig(processConfigId); - verify(processConfigRepository).findById(processConfigId); - assertThat(processConfig).isPresent(); - assertThat(processConfig.get().processConfig()).usingRecursiveComparison().isEqualTo(securityAnalysisConfig); - } - - @Test - void getProcessConfigNotFound() { - UUID processConfigId = UUID.randomUUID(); - - when(processConfigRepository.findById(processConfigId)).thenReturn(Optional.empty()); - - Optional processConfig = processConfigService.getProcessConfig(processConfigId); - verify(processConfigRepository).findById(processConfigId); - assertThat(processConfig).isEmpty(); - } - - @Test - void getSecurityAnalysisConfigsMetadata() { - UUID processConfigId1 = UUID.randomUUID(); - UUID processConfigId2 = UUID.randomUUID(); + void createProcessConfig() { + UUID expectedProcessConfigUuid = UUID.randomUUID(); - SecurityAnalysisConfigEntity entity1 = securityAnalysisConfigHandler.toEntity(securityAnalysisConfig); - entity1.setId(processConfigId1); - SecurityAnalysisConfigEntity entity2 = securityAnalysisConfigHandler.toEntity(securityAnalysisConfig); - entity2.setId(processConfigId2); + ProcessConfigEntity savedEntity = mock(ProcessConfigEntity.class); - when(processConfigRepository.findAllById(List.of(processConfigId1, processConfigId2))) - .thenReturn(List.of(entity1, entity2)); + when(processConfig.processType()).thenReturn(PROCESS_TYPE); + when(handler.toEntity(processConfig)).thenReturn(processConfigEntity); + when(processConfigRepository.save(processConfigEntity)).thenReturn(savedEntity); + when(savedEntity.getId()).thenReturn(expectedProcessConfigUuid); - List metadataInfos = processConfigService.getProcessConfigsMetadata(List.of(processConfigId1, processConfigId2)); + UUID result = processConfigService.createProcessConfig(processConfig); - verify(processConfigRepository).findAllById(List.of(processConfigId1, processConfigId2)); - assertThat(metadataInfos).isEqualTo(List.of( - new MetadataInfos(processConfigId1, ProcessType.SECURITY_ANALYSIS), - new MetadataInfos(processConfigId2, ProcessType.SECURITY_ANALYSIS) - )); + assertThat(result).isEqualTo(expectedProcessConfigUuid); + verify(handler).toEntity(processConfig); + verify(processConfigRepository).save(processConfigEntity); } @Test - void updateSecurityAnalysisConfig() { - UUID processConfigId = UUID.randomUUID(); - SecurityAnalysisConfigEntity securityAnalysisConfigEntity = securityAnalysisConfigHandler.toEntity(securityAnalysisConfig); - - SecurityAnalysisConfig newSecurityAnalysisConfig = new SecurityAnalysisConfig( - UUID.randomUUID(), - List.of(UUID.randomUUID()), - UUID.randomUUID() - ); + void getProcessConfig() { + UUID processConfigUuid = UUID.randomUUID(); - when(processConfigRepository.findById(processConfigId)).thenReturn(Optional.of(securityAnalysisConfigEntity)); + when(processConfigRepository.findById(processConfigUuid)).thenReturn(Optional.of(processConfigEntity)); + when(processConfigEntity.getProcessType()).thenReturn(PROCESS_TYPE); + when(handler.toProcessConfig(processConfigEntity)).thenReturn(processConfig); + when(processConfigEntity.getId()).thenReturn(processConfigUuid); - Optional updatedConfigId = processConfigService.updateProcessConfig(processConfigId, newSecurityAnalysisConfig); - assertThat(updatedConfigId).isPresent(); + Optional result = processConfigService.getProcessConfig(processConfigUuid); - verify(processConfigRepository).findById(processConfigId); - - Optional processConfigUpdated = processConfigService.getProcessConfig(processConfigId); - assertThat(processConfigUpdated).isPresent(); - assertThat(processConfigUpdated.get().processConfig()).usingRecursiveComparison().isEqualTo(newSecurityAnalysisConfig); + assertThat(result).isPresent(); + assertThat(result.get().processConfig()).isEqualTo(processConfig); + verify(processConfigRepository).findById(processConfigUuid); + verify(handler).toProcessConfig(processConfigEntity); } @Test - void updateSecurityAnalysisConfigNotFound() { - UUID processConfigId = UUID.randomUUID(); + void getProcessConfigNotFound() { + UUID processConfigUuid = UUID.randomUUID(); - when(processConfigRepository.findById(processConfigId)).thenReturn(Optional.empty()); + when(processConfigRepository.findById(processConfigUuid)).thenReturn(Optional.empty()); - SecurityAnalysisConfig newSecurityAnalysisConfig = new SecurityAnalysisConfig( - UUID.randomUUID(), - List.of(UUID.randomUUID()), - UUID.randomUUID() - ); - Optional updatedProcessConfigId = processConfigService.updateProcessConfig(processConfigId, newSecurityAnalysisConfig); - assertThat(updatedProcessConfigId).isEmpty(); + Optional result = processConfigService.getProcessConfig(processConfigUuid); - verify(processConfigRepository).findById(processConfigId); + assertThat(result).isEmpty(); + verify(processConfigRepository).findById(processConfigUuid); + verify(handler, never()).toProcessConfig(any()); } @Test - void duplicateSecurityAnalysisConfig() { - UUID sourceProcessConfigId = UUID.randomUUID(); - UUID expectedNewProcessConfigId = UUID.randomUUID(); - - SecurityAnalysisConfigEntity sourceEntity = securityAnalysisConfigHandler.toEntity(securityAnalysisConfig); - sourceEntity.setId(sourceProcessConfigId); - - when(processConfigRepository.findById(sourceProcessConfigId)).thenReturn(Optional.of(sourceEntity)); - when(processConfigRepository.save(any(SecurityAnalysisConfigEntity.class))) - .thenAnswer(invocation -> { - SecurityAnalysisConfigEntity entity = invocation.getArgument(0); - entity.setId(expectedNewProcessConfigId); - return entity; - }); - - Optional newProcessConfigId = processConfigService.duplicateProcessConfig(sourceProcessConfigId); + void getProcessConfigs() { + UUID processConfigUuid = UUID.randomUUID(); - assertThat(newProcessConfigId).contains(expectedNewProcessConfigId); + when(processConfigRepository.findAllByProcessType(PROCESS_TYPE)).thenReturn(List.of(processConfigEntity)); + when(processConfigEntity.getProcessType()).thenReturn(PROCESS_TYPE); + when(handler.toProcessConfig(processConfigEntity)).thenReturn(processConfig); + when(processConfigEntity.getId()).thenReturn(processConfigUuid); - verify(processConfigRepository).findById(sourceProcessConfigId); - ArgumentCaptor captor = ArgumentCaptor.forClass(SecurityAnalysisConfigEntity.class); - verify(processConfigRepository).save(captor.capture()); + List result = processConfigService.getProcessConfigs(PROCESS_TYPE); - SecurityAnalysisConfigEntity savedEntity = captor.getValue(); - assertThat(savedEntity.getSecurityAnalysisParametersUuid()).isEqualTo(securityAnalysisConfig.securityAnalysisParametersUuid()); - assertThat(savedEntity.getLoadflowParametersUuid()).isEqualTo(securityAnalysisConfig.loadflowParametersUuid()); - assertThat(savedEntity.getModificationUuids()).isEqualTo(securityAnalysisConfig.modificationUuids()); + assertThat(result).hasSize(1); + assertThat(result.getFirst().processConfig()).isEqualTo(processConfig); + verify(processConfigRepository).findAllByProcessType(PROCESS_TYPE); + verify(handler).toProcessConfig(processConfigEntity); } @Test - void duplicateProcessConfigNotFound() { - UUID processConfigId = UUID.randomUUID(); + void getProcessConfigsMetadata() { + UUID saUuid = UUID.randomUUID(); + UUID lfUuid = UUID.randomUUID(); + List processConfigUuids = List.of(saUuid, lfUuid); - when(processConfigRepository.findById(processConfigId)).thenReturn(Optional.empty()); + SecurityAnalysisConfigEntity saEntity = new SecurityAnalysisConfigEntity(); + saEntity.setId(saUuid); + saEntity.setProcessType(ProcessType.SECURITY_ANALYSIS); + LoadFlowConfigEntity lfEntity = new LoadFlowConfigEntity(); + lfEntity.setId(lfUuid); + lfEntity.setProcessType(ProcessType.LOADFLOW); - Optional newProcessConfigId = processConfigService.duplicateProcessConfig(processConfigId); - assertThat(newProcessConfigId).isEmpty(); - verify(processConfigRepository).findById(processConfigId); - } - - @Test - void deleteProcessConfig() { - UUID processConfigId = UUID.randomUUID(); + when(processConfigRepository.findAllById(processConfigUuids)).thenReturn(List.of(saEntity, lfEntity)); - when(processConfigRepository.existsById(processConfigId)).thenReturn(Boolean.TRUE); - doNothing().when(processConfigRepository).deleteById(processConfigId); - - Optional deletedProcessConfigId = processConfigService.deleteProcessConfig(processConfigId); - assertThat(deletedProcessConfigId).contains(processConfigId); - - verify(processConfigRepository).existsById(processConfigId); - verify(processConfigRepository).deleteById(processConfigId); - } + List result = processConfigService.getProcessConfigsMetadata(processConfigUuids); - @Test - void deleteProcessConfigNotFound() { - UUID processConfigId = UUID.randomUUID(); - - when(processConfigRepository.existsById(processConfigId)).thenReturn(Boolean.FALSE); - - Optional deletedProcessConfigId = processConfigService.deleteProcessConfig(processConfigId); - assertThat(deletedProcessConfigId).isEmpty(); - - verify(processConfigRepository).existsById(processConfigId); - verify(processConfigRepository, never()).deleteById(processConfigId); + assertThat(result).isEqualTo(List.of( + new MetadataInfos(saUuid, ProcessType.SECURITY_ANALYSIS), + new MetadataInfos(lfUuid, ProcessType.LOADFLOW) + )); + verify(processConfigRepository).findAllById(processConfigUuids); } @Test - void getSecurityAnalysisConfigs() { - SecurityAnalysisConfig securityAnalysisConfig1 = new SecurityAnalysisConfig(UUID.randomUUID(), List.of(UUID.randomUUID(), UUID.randomUUID()), UUID.randomUUID()); - SecurityAnalysisConfigEntity securityAnalysisConfigEntity1 = securityAnalysisConfigHandler.toEntity(securityAnalysisConfig1); - SecurityAnalysisConfig securityAnalysisConfig2 = new SecurityAnalysisConfig(UUID.randomUUID(), List.of(UUID.randomUUID()), UUID.randomUUID()); - SecurityAnalysisConfigEntity securityAnalysisConfigEntity2 = securityAnalysisConfigHandler.toEntity(securityAnalysisConfig2); + void updateProcessConfig() { + UUID processConfigUuid = UUID.randomUUID(); - when(processConfigRepository.findAllByProcessType(ProcessType.SECURITY_ANALYSIS)) - .thenReturn(List.of(securityAnalysisConfigEntity1, securityAnalysisConfigEntity2)); + when(processConfigRepository.findById(processConfigUuid)).thenReturn(Optional.of(processConfigEntity)); + when(processConfigEntity.getProcessType()).thenReturn(PROCESS_TYPE); + when(processConfig.processType()).thenReturn(PROCESS_TYPE); + doNothing().when(handler).update(processConfig, processConfigEntity); - List processConfigs = processConfigService.getProcessConfigs(ProcessType.SECURITY_ANALYSIS); + Optional result = processConfigService.updateProcessConfig(processConfigUuid, processConfig); - verify(processConfigRepository).findAllByProcessType(ProcessType.SECURITY_ANALYSIS); - assertThat(processConfigs).hasSize(2); - assertThat(processConfigs.get(0).processConfig().processType()).isEqualTo(ProcessType.SECURITY_ANALYSIS); - assertThat(processConfigs.get(1).processConfig().processType()).isEqualTo(ProcessType.SECURITY_ANALYSIS); - - SecurityAnalysisConfig resSecurityAnalysisConfig1 = (SecurityAnalysisConfig) processConfigs.get(0).processConfig(); - assertThat(resSecurityAnalysisConfig1.securityAnalysisParametersUuid()).isEqualTo(securityAnalysisConfig1.securityAnalysisParametersUuid()); - assertThat(resSecurityAnalysisConfig1.modificationUuids()).isEqualTo(securityAnalysisConfig1.modificationUuids()); - - SecurityAnalysisConfig resSecurityAnalysisConfig2 = (SecurityAnalysisConfig) processConfigs.get(1).processConfig(); - assertThat(resSecurityAnalysisConfig2.securityAnalysisParametersUuid()).isEqualTo(securityAnalysisConfig2.securityAnalysisParametersUuid()); - assertThat(resSecurityAnalysisConfig2.modificationUuids()).isEqualTo(securityAnalysisConfig2.modificationUuids()); - } - - @Test - void getSecurityAnalysisConfigsNotFound() { - when(processConfigRepository.findAllByProcessType(ProcessType.SECURITY_ANALYSIS)).thenReturn(List.of()); - - List processConfigs = processConfigService.getProcessConfigs(ProcessType.SECURITY_ANALYSIS); - - verify(processConfigRepository).findAllByProcessType(ProcessType.SECURITY_ANALYSIS); - assertThat(processConfigs).isEmpty(); + assertThat(result) + .isPresent() + .contains(processConfigUuid); + verify(processConfigRepository).findById(processConfigUuid); + verify(handler).update(processConfig, processConfigEntity); } @Test - void createLoadFlowConfig() { - UUID expectedProcessConfigId = UUID.randomUUID(); - when(processConfigRepository.save(any(LoadFlowConfigEntity.class))) - .thenAnswer(invocation -> { - LoadFlowConfigEntity entity = invocation.getArgument(0); - entity.setId(expectedProcessConfigId); - return entity; - }); + void updateProcessConfigNotFound() { + UUID processConfigUuid = UUID.randomUUID(); - UUID result = processConfigService.createProcessConfig(loadFlowConfig); - assertThat(result).isEqualTo(expectedProcessConfigId); + when(processConfigRepository.findById(processConfigUuid)).thenReturn(Optional.empty()); - ArgumentCaptor captor = ArgumentCaptor.forClass(LoadFlowConfigEntity.class); - verify(processConfigRepository).save(captor.capture()); + Optional result = processConfigService.updateProcessConfig(processConfigUuid, processConfig); - LoadFlowConfigEntity savedEntity = captor.getValue(); - assertThat(savedEntity.getId()).isEqualTo(expectedProcessConfigId); - assertThat(savedEntity.getProcessType()).isEqualTo(ProcessType.LOADFLOW); - assertThat(savedEntity.getLoadflowParametersUuid()).isEqualTo(loadFlowConfig.loadflowParametersUuid()); - assertThat(savedEntity.getModificationUuids()).isEqualTo(loadFlowConfig.modificationUuids()); + assertThat(result).isEmpty(); + verify(processConfigRepository).findById(processConfigUuid); + verify(handler, never()).update(processConfig, processConfigEntity); } @Test - void getLoadFlowConfig() { - UUID processConfigId = UUID.randomUUID(); - LoadFlowConfigEntity loadFlowConfigEntity = loadFlowConfigHandler.toEntity(loadFlowConfig); + void updateProcessConfigWithProcessTypeMismatch() { + UUID processConfigUuid = UUID.randomUUID(); - when(processConfigRepository.findById(processConfigId)).thenReturn(Optional.of(loadFlowConfigEntity)); + when(processConfigRepository.findById(processConfigUuid)).thenReturn(Optional.of(processConfigEntity)); + when(processConfigEntity.getProcessType()).thenReturn(ProcessType.SECURITY_ANALYSIS); + when(processConfig.processType()).thenReturn(ProcessType.LOADFLOW); - Optional processConfig = processConfigService.getProcessConfig(processConfigId); - verify(processConfigRepository).findById(processConfigId); - assertThat(processConfig).isPresent(); - assertThat(processConfig.get().processConfig()).usingRecursiveComparison().isEqualTo(loadFlowConfig); + assertThatThrownBy(() -> processConfigService.updateProcessConfig(processConfigUuid, processConfig)) + .isInstanceOf(IllegalArgumentException.class); + verify(processConfigRepository).findById(processConfigUuid); + verify(handler, never()).update(processConfig, processConfigEntity); } @Test - void updateLoadFlowConfig() { - UUID processConfigId = UUID.randomUUID(); - LoadFlowConfigEntity loadFlowConfigEntity = loadFlowConfigHandler.toEntity(loadFlowConfig); - - LoadFlowConfig newLoadFlowConfig = new LoadFlowConfig( - UUID.randomUUID(), - List.of(UUID.randomUUID(), UUID.randomUUID()) - ); - - when(processConfigRepository.findById(processConfigId)).thenReturn(Optional.of(loadFlowConfigEntity)); - - Optional updatedProcessConfigId = processConfigService.updateProcessConfig(processConfigId, newLoadFlowConfig); - assertThat(updatedProcessConfigId).contains(processConfigId); - - verify(processConfigRepository).findById(processConfigId); - - Optional processConfigUpdated = processConfigService.getProcessConfig(processConfigId); - assertThat(processConfigUpdated).isPresent(); - assertThat(processConfigUpdated.get().processConfig()).usingRecursiveComparison().isEqualTo(newLoadFlowConfig); + void duplicateSecurityAnalysisConfig() { + UUID processConfigUuid = UUID.randomUUID(); + UUID copiedProcessConfigUuid = UUID.randomUUID(); + ProcessConfigEntity copiedProcessConfigEntity = Mockito.mock(ProcessConfigEntity.class); + + when(processConfigRepository.findById(processConfigUuid)).thenReturn(Optional.of(processConfigEntity)); + when(processConfigEntity.getProcessType()).thenReturn(PROCESS_TYPE); + when(handler.copyEntity(processConfigEntity)).thenReturn(copiedProcessConfigEntity); + when(processConfigRepository.save(copiedProcessConfigEntity)).thenReturn(copiedProcessConfigEntity); + when(copiedProcessConfigEntity.getId()).thenReturn(copiedProcessConfigUuid); + + Optional result = processConfigService.duplicateProcessConfig(processConfigUuid); + + assertThat(result) + .isPresent() + .contains(copiedProcessConfigUuid); + verify(processConfigRepository).findById(processConfigUuid); + verify(handler).copyEntity(processConfigEntity); + verify(processConfigRepository).save(copiedProcessConfigEntity); } @Test - void updateLoadFlowConfigNotFound() { - UUID processConfigId = UUID.randomUUID(); + void duplicateProcessConfigNotFound() { + UUID processConfigUuid = UUID.randomUUID(); - when(processConfigRepository.findById(processConfigId)).thenReturn(Optional.empty()); + when(processConfigRepository.findById(processConfigUuid)).thenReturn(Optional.empty()); - LoadFlowConfig newLoadFlowConfig = new LoadFlowConfig( - UUID.randomUUID(), - List.of(UUID.randomUUID(), UUID.randomUUID()) - ); + Optional result = processConfigService.duplicateProcessConfig(processConfigUuid); - Optional updatedProcessConfigId = processConfigService.updateProcessConfig(processConfigId, newLoadFlowConfig); - assertThat(updatedProcessConfigId).isNotPresent(); - - verify(processConfigRepository).findById(processConfigId); + assertThat(result).isEmpty(); + verify(processConfigRepository).findById(processConfigUuid); + verify(handler, never()).copyEntity(any()); } @Test - void updateProcessConfigWithTypeMismatchShouldThrow() { - UUID processConfigId = UUID.randomUUID(); - SecurityAnalysisConfigEntity entity = securityAnalysisConfigHandler.toEntity(securityAnalysisConfig); + void deleteProcessConfig() { + UUID processConfigUuid = UUID.randomUUID(); + when(processConfigRepository.existsById(processConfigUuid)).thenReturn(Boolean.TRUE); + doNothing().when(processConfigRepository).deleteById(processConfigUuid); - when(processConfigRepository.findById(processConfigId)).thenReturn(Optional.of(entity)); + Optional result = processConfigService.deleteProcessConfig(processConfigUuid); - assertThatThrownBy(() -> processConfigService.updateProcessConfig(processConfigId, loadFlowConfig)) - .isInstanceOf(IllegalArgumentException.class); + assertThat(result).contains(processConfigUuid); + verify(processConfigRepository).existsById(processConfigUuid); + verify(processConfigRepository).deleteById(processConfigUuid); } @Test - void duplicateLoadFlowConfig() { - UUID processConfigId = UUID.randomUUID(); - UUID expectedNewProcessConfigId = UUID.randomUUID(); - - LoadFlowConfigEntity sourceEntity = loadFlowConfigHandler.toEntity(loadFlowConfig); - sourceEntity.setId(processConfigId); - - when(processConfigRepository.findById(processConfigId)).thenReturn(Optional.of(sourceEntity)); - when(processConfigRepository.save(any(LoadFlowConfigEntity.class))) - .thenAnswer(invocation -> { - LoadFlowConfigEntity entity = invocation.getArgument(0); - entity.setId(expectedNewProcessConfigId); - return entity; - }); - - Optional newProcessConfigId = processConfigService.duplicateProcessConfig(processConfigId); + void deleteProcessConfigNotFound() { + UUID processConfigUuid = UUID.randomUUID(); - assertThat(newProcessConfigId).contains(expectedNewProcessConfigId); + when(processConfigRepository.existsById(processConfigUuid)).thenReturn(Boolean.FALSE); - verify(processConfigRepository).findById(processConfigId); - ArgumentCaptor captor = ArgumentCaptor.forClass(LoadFlowConfigEntity.class); - verify(processConfigRepository).save(captor.capture()); + Optional result = processConfigService.deleteProcessConfig(processConfigUuid); - LoadFlowConfigEntity savedEntity = captor.getValue(); - assertThat(savedEntity.getLoadflowParametersUuid()).isEqualTo(loadFlowConfig.loadflowParametersUuid()); - assertThat(savedEntity.getModificationUuids()).isEqualTo(loadFlowConfig.modificationUuids()); + assertThat(result).isEmpty(); + verify(processConfigRepository).existsById(processConfigUuid); + verify(processConfigRepository, never()).deleteById(any()); } @Test - void getLoadFlowConfigs() { - LoadFlowConfig loadFlowConfig1 = new LoadFlowConfig(UUID.randomUUID(), List.of(UUID.randomUUID(), UUID.randomUUID())); - LoadFlowConfigEntity loadFlowConfigEntity1 = loadFlowConfigHandler.toEntity(loadFlowConfig1); - - LoadFlowConfig loadFlowConfig2 = new LoadFlowConfig(UUID.randomUUID(), List.of(UUID.randomUUID())); - LoadFlowConfigEntity loadFlowConfigEntity2 = loadFlowConfigHandler.toEntity(loadFlowConfig2); - - when(processConfigRepository.findAllByProcessType(ProcessType.LOADFLOW)) - .thenReturn(List.of(loadFlowConfigEntity1, loadFlowConfigEntity2)); - - List processConfigs = processConfigService.getProcessConfigs(ProcessType.LOADFLOW); - - verify(processConfigRepository).findAllByProcessType(ProcessType.LOADFLOW); - assertThat(processConfigs).hasSize(2); - assertThat(processConfigs.get(0).processConfig().processType()).isEqualTo(ProcessType.LOADFLOW); - assertThat(processConfigs.get(1).processConfig().processType()).isEqualTo(ProcessType.LOADFLOW); - - LoadFlowConfig resLoadFlowConfig1 = (LoadFlowConfig) processConfigs.get(0).processConfig(); - assertThat(resLoadFlowConfig1.loadflowParametersUuid()).isEqualTo(loadFlowConfig1.loadflowParametersUuid()); - assertThat(resLoadFlowConfig1.modificationUuids()).isEqualTo(loadFlowConfig1.modificationUuids()); - - LoadFlowConfig resLoadFlowConfig2 = (LoadFlowConfig) processConfigs.get(1).processConfig(); - assertThat(resLoadFlowConfig2.loadflowParametersUuid()).isEqualTo(loadFlowConfig2.loadflowParametersUuid()); - assertThat(resLoadFlowConfig2.modificationUuids()).isEqualTo(loadFlowConfig2.modificationUuids()); + void compareProcessConfigsWithEqualProcessConfigs() { + UUID processConfigUuid1 = UUID.randomUUID(); + UUID processConfigUuid2 = UUID.randomUUID(); + ProcessConfigFieldComparison fieldComparison = new ProcessConfigFieldComparison("field", true, "value1", "value2"); + + when(processConfigRepository.findById(processConfigUuid1)).thenReturn(Optional.of(processConfigEntity)); + when(processConfigRepository.findById(processConfigUuid2)).thenReturn(Optional.of(processConfigEntity)); + when(processConfigEntity.getProcessType()).thenReturn(PROCESS_TYPE); + when(handler.computeDifferences(processConfigEntity, processConfigEntity)).thenReturn(List.of(fieldComparison)); + + Optional result = processConfigService.compareProcessConfigs(processConfigUuid1, processConfigUuid2); + + assertThat(result) + .isPresent() + .contains(new ProcessConfigComparison(processConfigUuid1, processConfigUuid2, true, List.of(fieldComparison))); + verify(processConfigRepository).findById(processConfigUuid1); + verify(processConfigRepository).findById(processConfigUuid2); + verify(handler).computeDifferences(processConfigEntity, processConfigEntity); } @Test - void getLoadFlowConfigsNotFound() { - when(processConfigRepository.findAllByProcessType(ProcessType.LOADFLOW)).thenReturn(List.of()); - - List processConfigs = processConfigService.getProcessConfigs(ProcessType.LOADFLOW); - - verify(processConfigRepository).findAllByProcessType(ProcessType.LOADFLOW); - assertThat(processConfigs).isEmpty(); + void compareProcessConfigsWithDifferentProcessConfigs() { + UUID processConfigUuid1 = UUID.randomUUID(); + UUID processConfigUuid2 = UUID.randomUUID(); + ProcessConfigEntity processConfigEntity1 = Mockito.mock(ProcessConfigEntity.class); + ProcessConfigEntity processConfigEntity2 = Mockito.mock(ProcessConfigEntity.class); + ProcessConfigFieldComparison fieldComparison = new ProcessConfigFieldComparison("field", false, "value1", "value2"); + + when(processConfigRepository.findById(processConfigUuid1)).thenReturn(Optional.of(processConfigEntity1)); + when(processConfigRepository.findById(processConfigUuid2)).thenReturn(Optional.of(processConfigEntity2)); + when(processConfigEntity1.getProcessType()).thenReturn(PROCESS_TYPE); + when(processConfigEntity2.getProcessType()).thenReturn(PROCESS_TYPE); + when(handler.computeDifferences(processConfigEntity1, processConfigEntity2)).thenReturn(List.of(fieldComparison)); + + Optional result = processConfigService.compareProcessConfigs(processConfigUuid1, processConfigUuid2); + + assertThat(result) + .isPresent() + .contains(new ProcessConfigComparison(processConfigUuid1, processConfigUuid2, false, List.of(fieldComparison))); + verify(processConfigRepository).findById(processConfigUuid1); + verify(processConfigRepository).findById(processConfigUuid2); + verify(handler).computeDifferences(processConfigEntity1, processConfigEntity2); } @Test - void getLoadFlowConfigsMetadata() { - UUID processConfigId1 = UUID.randomUUID(); - UUID processConfigId2 = UUID.randomUUID(); - - LoadFlowConfigEntity entity1 = loadFlowConfigHandler.toEntity(loadFlowConfig); - entity1.setId(processConfigId1); - LoadFlowConfigEntity entity2 = loadFlowConfigHandler.toEntity(loadFlowConfig); - entity2.setId(processConfigId2); + void compareProcessConfigWithFirstProcessConfigNotFound() { + UUID processConfigUuid1 = UUID.randomUUID(); + UUID processConfigUuid2 = UUID.randomUUID(); - when(processConfigRepository.findAllById(List.of(processConfigId1, processConfigId2))) - .thenReturn(List.of(entity1, entity2)); + // test when the first process config is not found + when(processConfigRepository.findById(processConfigUuid1)).thenReturn(Optional.empty()); - List metadataInfos = processConfigService.getProcessConfigsMetadata(List.of(processConfigId1, processConfigId2)); + Optional result = processConfigService.compareProcessConfigs(processConfigUuid1, processConfigUuid2); - verify(processConfigRepository).findAllById(List.of(processConfigId1, processConfigId2)); - assertThat(metadataInfos).isEqualTo(List.of( - new MetadataInfos(processConfigId1, ProcessType.LOADFLOW), - new MetadataInfos(processConfigId2, ProcessType.LOADFLOW) - )); + assertThat(result).isEmpty(); + verify(processConfigRepository).findById(processConfigUuid1); + verify(handler, never()).computeDifferences(any(), any()); } @Test - void compareProcessConfigsShouldReturnIdenticalWhenConfigsAreEqual() { - UUID uuid1 = UUID.randomUUID(); - UUID uuid2 = UUID.randomUUID(); - SecurityAnalysisConfig config = new SecurityAnalysisConfig(UUID.randomUUID(), List.of(UUID.randomUUID(), UUID.randomUUID()), UUID.randomUUID()); - - SecurityAnalysisConfigEntity entity1 = securityAnalysisConfigHandler.toEntity(config); - entity1.setId(uuid1); - SecurityAnalysisConfigEntity entity2 = securityAnalysisConfigHandler.toEntity(config); - entity2.setId(uuid2); - - when(processConfigRepository.findById(uuid1)).thenReturn(Optional.of(entity1)); - when(processConfigRepository.findById(uuid2)).thenReturn(Optional.of(entity2)); - - ProcessConfigComparison comparison = processConfigService.compareProcessConfigs(uuid1, uuid2); - - assertThat(comparison.processConfigUuid1()).isEqualTo(uuid1); - assertThat(comparison.processConfigUuid2()).isEqualTo(uuid2); - assertThat(comparison.identical()).isTrue(); - assertThat(comparison.differences()).hasSize(3); - assertThat(comparison.differences()).allMatch(ProcessConfigFieldComparison::identical); - } + void compareProcessConfigWithSecondProcessConfigNotFound() { + UUID processConfigUuid1 = UUID.randomUUID(); + UUID processConfigUuid2 = UUID.randomUUID(); - @Test - void compareProcessConfigsShouldReturnDifferencesWhenModificationsAreDifferent() { - UUID uuid1 = UUID.randomUUID(); - UUID uuid2 = UUID.randomUUID(); - UUID securityAnalysisParametersUuid = UUID.randomUUID(); - UUID loadflowParametersUuid = UUID.randomUUID(); - List modificationUuids1 = List.of(UUID.randomUUID(), UUID.randomUUID()); - List modificationUuids2 = List.of(UUID.randomUUID(), UUID.randomUUID()); - - SecurityAnalysisConfigEntity entity1 = securityAnalysisConfigHandler.toEntity( - new SecurityAnalysisConfig(securityAnalysisParametersUuid, modificationUuids1, loadflowParametersUuid)); - entity1.setId(uuid1); - SecurityAnalysisConfigEntity entity2 = securityAnalysisConfigHandler.toEntity( - new SecurityAnalysisConfig(securityAnalysisParametersUuid, modificationUuids2, loadflowParametersUuid)); - entity2.setId(uuid2); - - when(processConfigRepository.findById(uuid1)).thenReturn(Optional.of(entity1)); - when(processConfigRepository.findById(uuid2)).thenReturn(Optional.of(entity2)); - - ProcessConfigComparison comparison = processConfigService.compareProcessConfigs(uuid1, uuid2); - - assertThat(comparison.identical()).isFalse(); - assertThat(comparison.differences()).hasSize(3); - - ProcessConfigFieldComparison modificationsComparison = comparison.differences().stream() - .filter(d -> "modifications".equals(d.field())) - .findFirst() - .orElseThrow(); - assertThat(modificationsComparison.identical()).isFalse(); - assertThat(modificationsComparison.value1()).isEqualTo(modificationUuids1); - assertThat(modificationsComparison.value2()).isEqualTo(modificationUuids2); - } + // test when the second process config is not found + ProcessConfigEntity processConfigEntity1 = Mockito.mock(ProcessConfigEntity.class); - @Test - void compareProcessConfigsShouldReturnDifferencesWhenParametersAreDifferent() { - UUID uuid1 = UUID.randomUUID(); - UUID uuid2 = UUID.randomUUID(); - UUID securityAnalysisParametersUuid1 = UUID.randomUUID(); - UUID securityAnalysisParametersUuid2 = UUID.randomUUID(); - UUID loadflowParametersUuid = UUID.randomUUID(); - List modificationUuids = List.of(UUID.randomUUID()); - - SecurityAnalysisConfigEntity entity1 = securityAnalysisConfigHandler.toEntity( - new SecurityAnalysisConfig(securityAnalysisParametersUuid1, modificationUuids, loadflowParametersUuid)); - entity1.setId(uuid1); - SecurityAnalysisConfigEntity entity2 = securityAnalysisConfigHandler.toEntity( - new SecurityAnalysisConfig(securityAnalysisParametersUuid2, modificationUuids, loadflowParametersUuid)); - entity2.setId(uuid2); - - when(processConfigRepository.findById(uuid1)).thenReturn(Optional.of(entity1)); - when(processConfigRepository.findById(uuid2)).thenReturn(Optional.of(entity2)); - - ProcessConfigComparison comparison = processConfigService.compareProcessConfigs(uuid1, uuid2); - - assertThat(comparison.identical()).isFalse(); - - ProcessConfigFieldComparison parametersComparison = comparison.differences().stream() - .filter(d -> "securityAnalysisParameters".equals(d.field())) - .findFirst() - .orElseThrow(); - assertThat(parametersComparison.identical()).isFalse(); - assertThat(parametersComparison.value1()).isEqualTo(securityAnalysisParametersUuid1); - assertThat(parametersComparison.value2()).isEqualTo(securityAnalysisParametersUuid2); - } + when(processConfigRepository.findById(processConfigUuid1)).thenReturn(Optional.of(processConfigEntity1)); + when(processConfigRepository.findById(processConfigUuid2)).thenReturn(Optional.empty()); - @Test - void compareProcessConfigsShouldDetectOrderDifferenceInModifications() { - UUID uuid1 = UUID.randomUUID(); - UUID uuid2 = UUID.randomUUID(); - UUID securityAnalysisParametersUuid = UUID.randomUUID(); - UUID loadflowParametersUuid = UUID.randomUUID(); - UUID mod1 = UUID.randomUUID(); - UUID mod2 = UUID.randomUUID(); - List modificationUuids1 = List.of(mod1, mod2); - List modificationUuids2 = List.of(mod2, mod1); // Different order - - SecurityAnalysisConfigEntity entity1 = securityAnalysisConfigHandler.toEntity( - new SecurityAnalysisConfig(securityAnalysisParametersUuid, modificationUuids1, loadflowParametersUuid)); - entity1.setId(uuid1); - SecurityAnalysisConfigEntity entity2 = securityAnalysisConfigHandler.toEntity( - new SecurityAnalysisConfig(securityAnalysisParametersUuid, modificationUuids2, loadflowParametersUuid)); - entity2.setId(uuid2); - - when(processConfigRepository.findById(uuid1)).thenReturn(Optional.of(entity1)); - when(processConfigRepository.findById(uuid2)).thenReturn(Optional.of(entity2)); - - ProcessConfigComparison comparison = processConfigService.compareProcessConfigs(uuid1, uuid2); - - assertThat(comparison.identical()).isFalse(); - - ProcessConfigFieldComparison modificationsComparison = comparison.differences().stream() - .filter(d -> "modifications".equals(d.field())) - .findFirst() - .orElseThrow(); - assertThat(modificationsComparison.identical()).isFalse(); - } + Optional result = processConfigService.compareProcessConfigs(processConfigUuid1, processConfigUuid2); - @Test - void compareLoadFlowConfigsShouldReturnIdenticalWhenConfigsAreEqual() { - UUID uuid1 = UUID.randomUUID(); - UUID uuid2 = UUID.randomUUID(); - LoadFlowConfig config = new LoadFlowConfig(UUID.randomUUID(), List.of(UUID.randomUUID(), UUID.randomUUID())); - - LoadFlowConfigEntity entity1 = loadFlowConfigHandler.toEntity(config); - entity1.setId(uuid1); - LoadFlowConfigEntity entity2 = loadFlowConfigHandler.toEntity(config); - entity2.setId(uuid2); - - when(processConfigRepository.findById(uuid1)).thenReturn(Optional.of(entity1)); - when(processConfigRepository.findById(uuid2)).thenReturn(Optional.of(entity2)); - - ProcessConfigComparison comparison = processConfigService.compareProcessConfigs(uuid1, uuid2); - - assertThat(comparison.processConfigUuid1()).isEqualTo(uuid1); - assertThat(comparison.processConfigUuid2()).isEqualTo(uuid2); - assertThat(comparison.identical()).isTrue(); - assertThat(comparison.differences()).hasSize(2); - assertThat(comparison.differences()).allMatch(ProcessConfigFieldComparison::identical); - } - - @Test - void compareLoadFlowConfigsShouldReturnDifferencesWhenModificationsAreDifferent() { - UUID uuid1 = UUID.randomUUID(); - UUID uuid2 = UUID.randomUUID(); - UUID loadflowParametersUuid = UUID.randomUUID(); - List modificationUuids1 = List.of(UUID.randomUUID(), UUID.randomUUID()); - List modificationUuids2 = List.of(UUID.randomUUID(), UUID.randomUUID()); - - LoadFlowConfigEntity entity1 = loadFlowConfigHandler.toEntity(new LoadFlowConfig(loadflowParametersUuid, modificationUuids1)); - entity1.setId(uuid1); - LoadFlowConfigEntity entity2 = loadFlowConfigHandler.toEntity(new LoadFlowConfig(loadflowParametersUuid, modificationUuids2)); - entity2.setId(uuid2); - - when(processConfigRepository.findById(uuid1)).thenReturn(Optional.of(entity1)); - when(processConfigRepository.findById(uuid2)).thenReturn(Optional.of(entity2)); - - ProcessConfigComparison comparison = processConfigService.compareProcessConfigs(uuid1, uuid2); - - assertThat(comparison.identical()).isFalse(); - assertThat(comparison.differences()).hasSize(2); - - ProcessConfigFieldComparison modificationsComparison = comparison.differences().stream() - .filter(d -> "modifications".equals(d.field())) - .findFirst() - .orElseThrow(); - assertThat(modificationsComparison.identical()).isFalse(); - assertThat(modificationsComparison.value1()).isEqualTo(modificationUuids1); - assertThat(modificationsComparison.value2()).isEqualTo(modificationUuids2); - } - - @Test - void compareLoadFlowConfigsShouldReturnDifferencesWhenParametersAreDifferent() { - UUID uuid1 = UUID.randomUUID(); - UUID uuid2 = UUID.randomUUID(); - UUID loadflowParametersUuid1 = UUID.randomUUID(); - UUID loadflowParametersUuid2 = UUID.randomUUID(); - List modificationUuids = List.of(UUID.randomUUID()); - - LoadFlowConfigEntity entity1 = loadFlowConfigHandler.toEntity(new LoadFlowConfig(loadflowParametersUuid1, modificationUuids)); - entity1.setId(uuid1); - LoadFlowConfigEntity entity2 = loadFlowConfigHandler.toEntity(new LoadFlowConfig(loadflowParametersUuid2, modificationUuids)); - entity2.setId(uuid2); - - when(processConfigRepository.findById(uuid1)).thenReturn(Optional.of(entity1)); - when(processConfigRepository.findById(uuid2)).thenReturn(Optional.of(entity2)); - - ProcessConfigComparison comparison = processConfigService.compareProcessConfigs(uuid1, uuid2); - - assertThat(comparison.identical()).isFalse(); - - ProcessConfigFieldComparison parametersComparison = comparison.differences().stream() - .filter(d -> "loadflowParameters".equals(d.field())) - .findFirst() - .orElseThrow(); - assertThat(parametersComparison.identical()).isFalse(); - assertThat(parametersComparison.value1()).isEqualTo(loadflowParametersUuid1); - assertThat(parametersComparison.value2()).isEqualTo(loadflowParametersUuid2); + assertThat(result).isEmpty(); + verify(processConfigRepository).findById(processConfigUuid1); + verify(processConfigRepository).findById(processConfigUuid2); + verify(handler, never()).computeDifferences(any(), any()); } @Test - void compareProcessConfigsShouldReturnEmptyWhenOneConfigNotFound() { - UUID uuid1 = UUID.randomUUID(); - UUID uuid2 = UUID.randomUUID(); - - when(processConfigRepository.findById(uuid1)).thenReturn(Optional.empty()); - - assertThatThrownBy(() -> - processConfigService.compareProcessConfigs(uuid1, uuid2) - ) + void compareProcessConfigsShouldThrowWhenProcessTypesAreDifferent() { + UUID processConfigUuid1 = UUID.randomUUID(); + UUID processConfigUuid2 = UUID.randomUUID(); + ProcessConfigEntity processConfigEntity1 = Mockito.mock(ProcessConfigEntity.class); + ProcessConfigEntity processConfigEntity2 = Mockito.mock(ProcessConfigEntity.class); + + when(processConfigRepository.findById(processConfigUuid1)).thenReturn(Optional.of(processConfigEntity1)); + when(processConfigRepository.findById(processConfigUuid2)).thenReturn(Optional.of(processConfigEntity2)); + when(processConfigEntity1.getProcessType()).thenReturn(ProcessType.LOADFLOW); + when(processConfigEntity2.getProcessType()).thenReturn(ProcessType.SECURITY_ANALYSIS); + + assertThatThrownBy(() -> processConfigService.compareProcessConfigs(processConfigUuid1, processConfigUuid2)) .isInstanceOf(MonitorServerException.class) .satisfies(ex -> { MonitorServerException e = (MonitorServerException) ex; - assertEquals("Process config not found", e.getMessage()); - assertThat(e.getBusinessErrorValues()).containsEntry("processConfigUuid", uuid1); + assertThat(e.getErrorCode()).isEqualTo(DIFFERENT_PROCESS_CONFIG_TYPE); + assertThat(e.getBusinessErrorValues()) + .containsEntry("processConfigEntity1Type", ProcessType.LOADFLOW) + .containsEntry("processConfigEntity2Type", ProcessType.SECURITY_ANALYSIS); }); + verify(processConfigRepository).findById(processConfigUuid1); + verify(processConfigRepository).findById(processConfigUuid2); + verify(handler, never()).computeDifferences(any(), any()); } - - @Test - void compareProcessConfigsShouldThrowWhenDifferentTypes() { - UUID uuid1 = UUID.randomUUID(); - UUID uuid2 = UUID.randomUUID(); - - SecurityAnalysisConfigEntity entity1 = securityAnalysisConfigHandler.toEntity(securityAnalysisConfig); - entity1.setId(uuid1); - LoadFlowConfigEntity entity2 = loadFlowConfigHandler.toEntity(loadFlowConfig); - entity2.setId(uuid2); - - when(processConfigRepository.findById(uuid1)).thenReturn(Optional.of(entity1)); - when(processConfigRepository.findById(uuid2)).thenReturn(Optional.of(entity2)); - - MonitorServerException exception = (MonitorServerException) catchThrowable(() -> processConfigService.compareProcessConfigs(uuid1, uuid2)); - assertThat(exception.getErrorCode()).isEqualTo(DIFFERENT_PROCESS_CONFIG_TYPE); - assertThat(exception.getBusinessErrorValues()).containsEntry("processConfigEntity1Type", ProcessType.SECURITY_ANALYSIS); - assertThat(exception.getBusinessErrorValues()).containsEntry("processConfigEntity2Type", ProcessType.LOADFLOW); - } - - // TODO: @ParameterizedTest void getHandlerTest(ProcessType) } diff --git a/monitor-server/src/test/java/org/gridsuite/monitor/server/services/processconfig/SecurityAnalysisConfigHandlerTest.java b/monitor-server/src/test/java/org/gridsuite/monitor/server/services/processconfig/SecurityAnalysisConfigHandlerTest.java new file mode 100644 index 00000000..161ed703 --- /dev/null +++ b/monitor-server/src/test/java/org/gridsuite/monitor/server/services/processconfig/SecurityAnalysisConfigHandlerTest.java @@ -0,0 +1,194 @@ +/* + * Copyright (c) 2026, RTE (http://www.rte-france.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ +package org.gridsuite.monitor.server.services.processconfig; + +import org.gridsuite.monitor.commons.types.processconfig.SecurityAnalysisConfig; +import org.gridsuite.monitor.commons.types.processexecution.ProcessType; +import org.gridsuite.monitor.server.dto.processconfig.ProcessConfigFieldComparison; +import org.gridsuite.monitor.server.entities.processconfig.SecurityAnalysisConfigEntity; +import org.gridsuite.monitor.server.mappers.processconfig.SecurityAnalysisConfigMapper; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mapstruct.factory.Mappers; +import org.mockito.Mockito; +import org.mockito.junit.jupiter.MockitoExtension; + +import java.util.List; +import java.util.UUID; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +/** + * @author Caroline Jeandat {@literal } + */ +@ExtendWith(MockitoExtension.class) +class SecurityAnalysisConfigHandlerTest extends AbstractProcessConfigHandlerTest { + @Override + ProcessType getProcessType() { + return ProcessType.SECURITY_ANALYSIS; + } + + @Override + SecurityAnalysisConfig createProcessConfig() { + return new SecurityAnalysisConfig(UUID.randomUUID(), List.of(UUID.randomUUID()), UUID.randomUUID()); + } + + @Override + SecurityAnalysisConfigEntity createProcessConfigEntity() { + return new SecurityAnalysisConfigEntity(); + } + + @Override + @BeforeEach + protected void setUp() { + SecurityAnalysisConfigMapper realMapper = Mappers.getMapper(SecurityAnalysisConfigMapper.class); + mapper = Mockito.spy(realMapper); + handler = new SecurityAnalysisConfigHandler(mapper); + } + + @Test + void computeDifferencesShouldReturnNoDifferenceWhenConfigsAreEqual() { + SecurityAnalysisConfig processConfig = createProcessConfig(); + SecurityAnalysisConfigEntity entity1 = createProcessConfigEntity(); + SecurityAnalysisConfigEntity entity2 = createProcessConfigEntity(); + + when(mapper.toDto(entity1)).thenReturn(processConfig); + when(mapper.toDto(entity2)).thenReturn(processConfig); + + List result = handler.computeDifferences(entity1, entity2); + + assertThat(result) + .hasSize(3) + .allMatch(ProcessConfigFieldComparison::identical) + .allMatch(fieldComparison -> fieldComparison.value1().equals(fieldComparison.value2())); + } + + @Test + void computeDifferencesShouldReturnDifferentModificationsWhenModificationsAreDifferent() { + UUID securityAnalysisParametersUuid = UUID.randomUUID(); + List modificationUuids1 = List.of(UUID.randomUUID(), UUID.randomUUID()); + List modificationUuids2 = List.of(UUID.randomUUID(), UUID.randomUUID()); + UUID loadflowParametersUuid = UUID.randomUUID(); + + SecurityAnalysisConfig processConfig1 = new SecurityAnalysisConfig(securityAnalysisParametersUuid, modificationUuids1, loadflowParametersUuid); + SecurityAnalysisConfig processConfig2 = new SecurityAnalysisConfig(securityAnalysisParametersUuid, modificationUuids2, loadflowParametersUuid); + + SecurityAnalysisConfigEntity entity1 = Mockito.mock(SecurityAnalysisConfigEntity.class); + SecurityAnalysisConfigEntity entity2 = Mockito.mock(SecurityAnalysisConfigEntity.class); + + when(mapper.toDto(entity1)).thenReturn(processConfig1); + when(mapper.toDto(entity2)).thenReturn(processConfig2); + + List result = handler.computeDifferences(entity1, entity2); + + assertThat(result).hasSize(3); + ProcessConfigFieldComparison comparison = result.stream() + .filter(d -> "modifications".equals(d.field())) + .findFirst() + .orElseThrow(); + assertThat(comparison.identical()).isFalse(); + assertThat(comparison.value1()).isEqualTo(modificationUuids1); + assertThat(comparison.value2()).isEqualTo(modificationUuids2); + verify(mapper).toDto(entity1); + verify(mapper).toDto(entity2); + } + + @Test + void computeDifferencesShouldDetectOrderDifferenceInModifications() { + UUID securityAnalysisParametersUuid = UUID.randomUUID(); + UUID mod1 = UUID.randomUUID(); + UUID mod2 = UUID.randomUUID(); + List modificationUuids1 = List.of(mod1, mod2); + List modificationUuids2 = List.of(mod2, mod1); // Different order + UUID loadflowParametersUuid = UUID.randomUUID(); + + SecurityAnalysisConfig processConfig1 = new SecurityAnalysisConfig(securityAnalysisParametersUuid, modificationUuids1, loadflowParametersUuid); + SecurityAnalysisConfig processConfig2 = new SecurityAnalysisConfig(securityAnalysisParametersUuid, modificationUuids2, loadflowParametersUuid); + + SecurityAnalysisConfigEntity entity1 = Mockito.mock(SecurityAnalysisConfigEntity.class); + SecurityAnalysisConfigEntity entity2 = Mockito.mock(SecurityAnalysisConfigEntity.class); + + when(mapper.toDto(entity1)).thenReturn(processConfig1); + when(mapper.toDto(entity2)).thenReturn(processConfig2); + + List result = handler.computeDifferences(entity1, entity2); + + assertThat(result).hasSize(3); + ProcessConfigFieldComparison comparison = result.stream() + .filter(d -> "modifications".equals(d.field())) + .findFirst() + .orElseThrow(); + assertThat(comparison.identical()).isFalse(); + assertThat(comparison.value1()).isEqualTo(modificationUuids1); + assertThat(comparison.value2()).isEqualTo(modificationUuids2); + verify(mapper).toDto(entity1); + verify(mapper).toDto(entity2); + } + + @Test + void computeDifferencesShouldReturnDifferencesWhenSecurityAnalysisParametersAreDifferent() { + UUID securityAnalysisParametersUuid1 = UUID.randomUUID(); + UUID securityAnalysisParametersUuid2 = UUID.randomUUID(); + List modificationUuids = List.of(UUID.randomUUID(), UUID.randomUUID()); + UUID loadflowParametersUuid = UUID.randomUUID(); + + SecurityAnalysisConfig processConfig1 = new SecurityAnalysisConfig(securityAnalysisParametersUuid1, modificationUuids, loadflowParametersUuid); + SecurityAnalysisConfig processConfig2 = new SecurityAnalysisConfig(securityAnalysisParametersUuid2, modificationUuids, loadflowParametersUuid); + + SecurityAnalysisConfigEntity entity1 = Mockito.mock(SecurityAnalysisConfigEntity.class); + SecurityAnalysisConfigEntity entity2 = Mockito.mock(SecurityAnalysisConfigEntity.class); + + when(mapper.toDto(entity1)).thenReturn(processConfig1); + when(mapper.toDto(entity2)).thenReturn(processConfig2); + + List result = handler.computeDifferences(entity1, entity2); + + assertThat(result).hasSize(3); + ProcessConfigFieldComparison comparison = result.stream() + .filter(d -> "securityAnalysisParameters".equals(d.field())) + .findFirst() + .orElseThrow(); + assertThat(comparison.identical()).isFalse(); + assertThat(comparison.value1()).isEqualTo(securityAnalysisParametersUuid1); + assertThat(comparison.value2()).isEqualTo(securityAnalysisParametersUuid2); + verify(mapper).toDto(entity1); + verify(mapper).toDto(entity2); + } + + @Test + void computeDifferencesShouldReturnDifferencesWhenLoadflowParametersAreDifferent() { + UUID securityAnalysisParametersUuid = UUID.randomUUID(); + List modificationUuids = List.of(UUID.randomUUID(), UUID.randomUUID()); + UUID loadflowParametersUuid1 = UUID.randomUUID(); + UUID loadflowParametersUuid2 = UUID.randomUUID(); + + SecurityAnalysisConfig processConfig1 = new SecurityAnalysisConfig(securityAnalysisParametersUuid, modificationUuids, loadflowParametersUuid1); + SecurityAnalysisConfig processConfig2 = new SecurityAnalysisConfig(securityAnalysisParametersUuid, modificationUuids, loadflowParametersUuid2); + + SecurityAnalysisConfigEntity entity1 = Mockito.mock(SecurityAnalysisConfigEntity.class); + SecurityAnalysisConfigEntity entity2 = Mockito.mock(SecurityAnalysisConfigEntity.class); + + when(mapper.toDto(entity1)).thenReturn(processConfig1); + when(mapper.toDto(entity2)).thenReturn(processConfig2); + + List result = handler.computeDifferences(entity1, entity2); + + assertThat(result).hasSize(3); + ProcessConfigFieldComparison comparison = result.stream() + .filter(d -> "loadflowParameters".equals(d.field())) + .findFirst() + .orElseThrow(); + assertThat(comparison.identical()).isFalse(); + assertThat(comparison.value1()).isEqualTo(loadflowParametersUuid1); + assertThat(comparison.value2()).isEqualTo(loadflowParametersUuid2); + verify(mapper).toDto(entity1); + verify(mapper).toDto(entity2); + } +} From 16d54de9fd21911a1e3079bfefc1242120ac5461 Mon Sep 17 00:00:00 2001 From: Caroline Jeandat Date: Wed, 24 Jun 2026 14:32:11 +0200 Subject: [PATCH 4/9] review comments: move method compareDifferences to ProcessConfig Signed-off-by: Caroline Jeandat --- monitor-commons/pom.xml | 19 +++ .../error/MonitorBusinessErrorCode.java | 26 ++++ .../commons/error/MonitorException.java | 46 ++++++ .../error/MonitorExceptionHandler.java | 47 ++++++ .../types/processconfig/LoadFlowConfig.java | 21 +++ .../types/processconfig/ProcessConfig.java | 2 + .../ProcessConfigFieldComparison.java | 4 +- .../processconfig/SecurityAnalysisConfig.java | 24 +++ .../error/MonitorBusinessErrorCodeTest.java | 23 +++ .../error/MonitorExceptionHandlerTest.java | 40 +++++ .../processconfig/LoadFlowConfigTest.java | 116 ++++++++++++++ .../SecurityAnalysisConfigTest.java | 141 +++++++++++++++++ .../ProcessConfigComparison.java | 1 + .../error/MonitorServerBusinessErrorCode.java | 4 +- .../server/error/MonitorServerException.java | 2 +- .../error/MonitorServerExceptionHandler.java | 2 +- .../processconfig/LoadFlowConfigHandler.java | 30 ---- .../processconfig/ProcessConfigHandler.java | 5 - .../processconfig/ProcessConfigService.java | 13 +- .../SecurityAnalysisConfigHandler.java | 39 ----- .../ProcessConfigControllerTest.java | 11 +- .../MonitorServerExceptionHandlerTest.java | 7 +- .../LoadFlowConfigHandlerTest.java | 112 -------------- .../ProcessConfigServiceTest.java | 61 +++++--- .../SecurityAnalysisConfigHandlerTest.java | 145 ------------------ 25 files changed, 568 insertions(+), 373 deletions(-) create mode 100644 monitor-commons/src/main/java/org/gridsuite/monitor/commons/error/MonitorBusinessErrorCode.java create mode 100644 monitor-commons/src/main/java/org/gridsuite/monitor/commons/error/MonitorException.java create mode 100644 monitor-commons/src/main/java/org/gridsuite/monitor/commons/error/MonitorExceptionHandler.java rename {monitor-server/src/main/java/org/gridsuite/monitor/server/dto => monitor-commons/src/main/java/org/gridsuite/monitor/commons/types}/processconfig/ProcessConfigFieldComparison.java (90%) create mode 100644 monitor-commons/src/test/java/org/gridsuite/monitor/commons/error/MonitorBusinessErrorCodeTest.java create mode 100644 monitor-commons/src/test/java/org/gridsuite/monitor/commons/error/MonitorExceptionHandlerTest.java create mode 100644 monitor-commons/src/test/java/org/gridsuite/monitor/commons/types/processconfig/LoadFlowConfigTest.java create mode 100644 monitor-commons/src/test/java/org/gridsuite/monitor/commons/types/processconfig/SecurityAnalysisConfigTest.java diff --git a/monitor-commons/pom.xml b/monitor-commons/pom.xml index 7f7cbb18..85efcf14 100644 --- a/monitor-commons/pom.xml +++ b/monitor-commons/pom.xml @@ -33,5 +33,24 @@ 2.2.22 provided + + com.powsybl + powsybl-ws-commons + + + org.junit.jupiter + junit-jupiter-params + test + + + org.assertj + assertj-core + test + + + org.springframework + spring-test + test + diff --git a/monitor-commons/src/main/java/org/gridsuite/monitor/commons/error/MonitorBusinessErrorCode.java b/monitor-commons/src/main/java/org/gridsuite/monitor/commons/error/MonitorBusinessErrorCode.java new file mode 100644 index 00000000..cc4b2c31 --- /dev/null +++ b/monitor-commons/src/main/java/org/gridsuite/monitor/commons/error/MonitorBusinessErrorCode.java @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2026, RTE (http://www.rte-france.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ +package org.gridsuite.monitor.commons.error; + +import com.powsybl.ws.commons.error.BusinessErrorCode; + +/** + * @author Franck Lecuyer + */ +public enum MonitorBusinessErrorCode implements BusinessErrorCode { + DIFFERENT_PROCESS_CONFIG_TYPE("monitor.differentProcessConfigType"); + + private final String code; + + MonitorBusinessErrorCode(String code) { + this.code = code; + } + + public String value() { + return code; + } +} diff --git a/monitor-commons/src/main/java/org/gridsuite/monitor/commons/error/MonitorException.java b/monitor-commons/src/main/java/org/gridsuite/monitor/commons/error/MonitorException.java new file mode 100644 index 00000000..e6359073 --- /dev/null +++ b/monitor-commons/src/main/java/org/gridsuite/monitor/commons/error/MonitorException.java @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2026, RTE (http://www.rte-france.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ +package org.gridsuite.monitor.commons.error; + +import com.powsybl.ws.commons.error.AbstractBusinessException; +import lombok.Getter; +import lombok.NonNull; + +import java.util.Map; + +/** + * @author Franck Lecuyer + */ +@Getter +public class MonitorException extends AbstractBusinessException { + private final MonitorBusinessErrorCode errorCode; + private final transient Map businessErrorValues; + + public MonitorException(MonitorBusinessErrorCode errorCode, String message) { + this(errorCode, message, null, null); + } + + public MonitorException(MonitorBusinessErrorCode errorCode, String message, Throwable cause) { + this(errorCode, message, null, cause); + } + + public MonitorException(MonitorBusinessErrorCode errorCode, String message, Map businessErrorValues) { + this(errorCode, message, businessErrorValues, null); + } + + public MonitorException(MonitorBusinessErrorCode errorCode, String message, Map businessErrorValues, Throwable cause) { + super(message, cause); + this.errorCode = errorCode; + this.businessErrorValues = businessErrorValues != null ? Map.copyOf(businessErrorValues) : Map.of(); + } + + @NonNull + @Override + public MonitorBusinessErrorCode getBusinessErrorCode() { + return errorCode; + } +} diff --git a/monitor-commons/src/main/java/org/gridsuite/monitor/commons/error/MonitorExceptionHandler.java b/monitor-commons/src/main/java/org/gridsuite/monitor/commons/error/MonitorExceptionHandler.java new file mode 100644 index 00000000..8fc21fd1 --- /dev/null +++ b/monitor-commons/src/main/java/org/gridsuite/monitor/commons/error/MonitorExceptionHandler.java @@ -0,0 +1,47 @@ +/** + * Copyright (c) 2026, RTE (http://www.rte-france.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ +package org.gridsuite.monitor.commons.error; + +import com.powsybl.ws.commons.error.AbstractBusinessExceptionHandler; +import com.powsybl.ws.commons.error.PowsyblWsProblemDetail; +import com.powsybl.ws.commons.error.ServerNameProvider; +import jakarta.servlet.http.HttpServletRequest; +import lombok.NonNull; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.ControllerAdvice; +import org.springframework.web.bind.annotation.ExceptionHandler; + +/** + * @author Franck Lecuyer + */ +@ControllerAdvice +public class MonitorExceptionHandler extends AbstractBusinessExceptionHandler { + + public MonitorExceptionHandler(ServerNameProvider serverNameProvider) { + super(serverNameProvider); + } + + @NonNull + @Override + protected MonitorBusinessErrorCode getBusinessCode(MonitorException ex) { + return ex.getBusinessErrorCode(); + } + + @Override + protected HttpStatus mapStatus(MonitorBusinessErrorCode errorCode) { + return switch (errorCode) { + case DIFFERENT_PROCESS_CONFIG_TYPE -> HttpStatus.BAD_REQUEST; + }; + } + + @ExceptionHandler(MonitorException.class) + protected ResponseEntity handleMonitorServerException( + MonitorException exception, HttpServletRequest request) { + return super.handleDomainException(exception, request); + } +} diff --git a/monitor-commons/src/main/java/org/gridsuite/monitor/commons/types/processconfig/LoadFlowConfig.java b/monitor-commons/src/main/java/org/gridsuite/monitor/commons/types/processconfig/LoadFlowConfig.java index 1e0abee4..7f87e751 100644 --- a/monitor-commons/src/main/java/org/gridsuite/monitor/commons/types/processconfig/LoadFlowConfig.java +++ b/monitor-commons/src/main/java/org/gridsuite/monitor/commons/types/processconfig/LoadFlowConfig.java @@ -7,11 +7,16 @@ package org.gridsuite.monitor.commons.types.processconfig; import jakarta.validation.constraints.NotNull; +import org.gridsuite.monitor.commons.error.MonitorException; import org.gridsuite.monitor.commons.types.processexecution.ProcessType; import java.util.List; +import java.util.Map; +import java.util.Objects; import java.util.UUID; +import static org.gridsuite.monitor.commons.error.MonitorBusinessErrorCode.DIFFERENT_PROCESS_CONFIG_TYPE; + /** * @author Franck Lecuyer */ @@ -25,4 +30,20 @@ public record LoadFlowConfig( public ProcessType processType() { return ProcessType.LOADFLOW; } + + @Override + public List compareWith(ProcessConfig other) { + if (!(other instanceof LoadFlowConfig o)) { + throw new MonitorException(DIFFERENT_PROCESS_CONFIG_TYPE, "Cannot compare different process config types", + Map.of("processConfigEntity1Type", this.processType(), "processConfigEntity2Type", other.processType())); + } + return List.of( + new ProcessConfigFieldComparison("modifications", + Objects.equals(this.modificationUuids, o.modificationUuids), + this.modificationUuids, o.modificationUuids), + new ProcessConfigFieldComparison("loadflowParameters", + Objects.equals(this.loadflowParametersUuid, o.loadflowParametersUuid), + this.loadflowParametersUuid, o.loadflowParametersUuid) + ); + } } diff --git a/monitor-commons/src/main/java/org/gridsuite/monitor/commons/types/processconfig/ProcessConfig.java b/monitor-commons/src/main/java/org/gridsuite/monitor/commons/types/processconfig/ProcessConfig.java index 98de853d..fbaec07a 100644 --- a/monitor-commons/src/main/java/org/gridsuite/monitor/commons/types/processconfig/ProcessConfig.java +++ b/monitor-commons/src/main/java/org/gridsuite/monitor/commons/types/processconfig/ProcessConfig.java @@ -29,4 +29,6 @@ public interface ProcessConfig { ProcessType processType(); List modificationUuids(); + + List compareWith(ProcessConfig other); } diff --git a/monitor-server/src/main/java/org/gridsuite/monitor/server/dto/processconfig/ProcessConfigFieldComparison.java b/monitor-commons/src/main/java/org/gridsuite/monitor/commons/types/processconfig/ProcessConfigFieldComparison.java similarity index 90% rename from monitor-server/src/main/java/org/gridsuite/monitor/server/dto/processconfig/ProcessConfigFieldComparison.java rename to monitor-commons/src/main/java/org/gridsuite/monitor/commons/types/processconfig/ProcessConfigFieldComparison.java index 71fd2310..1983fdc6 100644 --- a/monitor-server/src/main/java/org/gridsuite/monitor/server/dto/processconfig/ProcessConfigFieldComparison.java +++ b/monitor-commons/src/main/java/org/gridsuite/monitor/commons/types/processconfig/ProcessConfigFieldComparison.java @@ -1,10 +1,10 @@ -/** +/* * Copyright (c) 2026, RTE (http://www.rte-france.com) * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -package org.gridsuite.monitor.server.dto.processconfig; +package org.gridsuite.monitor.commons.types.processconfig; import io.swagger.v3.oas.annotations.media.Schema; diff --git a/monitor-commons/src/main/java/org/gridsuite/monitor/commons/types/processconfig/SecurityAnalysisConfig.java b/monitor-commons/src/main/java/org/gridsuite/monitor/commons/types/processconfig/SecurityAnalysisConfig.java index 2cd1611d..a03dca4a 100644 --- a/monitor-commons/src/main/java/org/gridsuite/monitor/commons/types/processconfig/SecurityAnalysisConfig.java +++ b/monitor-commons/src/main/java/org/gridsuite/monitor/commons/types/processconfig/SecurityAnalysisConfig.java @@ -7,11 +7,16 @@ package org.gridsuite.monitor.commons.types.processconfig; import jakarta.validation.constraints.NotNull; +import org.gridsuite.monitor.commons.error.MonitorException; import org.gridsuite.monitor.commons.types.processexecution.ProcessType; import java.util.List; +import java.util.Map; +import java.util.Objects; import java.util.UUID; +import static org.gridsuite.monitor.commons.error.MonitorBusinessErrorCode.DIFFERENT_PROCESS_CONFIG_TYPE; + /** * @author Antoine Bouhours */ @@ -27,4 +32,23 @@ public record SecurityAnalysisConfig( public ProcessType processType() { return ProcessType.SECURITY_ANALYSIS; } + + @Override + public List compareWith(ProcessConfig other) { + if (!(other instanceof SecurityAnalysisConfig o)) { + throw new MonitorException(DIFFERENT_PROCESS_CONFIG_TYPE, "Cannot compare different process config types", + Map.of("processConfigEntity1Type", this.processType(), "processConfigEntity2Type", other.processType())); + } + return List.of( + new ProcessConfigFieldComparison("modifications", + Objects.equals(this.modificationUuids, o.modificationUuids), + this.modificationUuids, o.modificationUuids), + new ProcessConfigFieldComparison("securityAnalysisParameters", + Objects.equals(this.securityAnalysisParametersUuid, o.securityAnalysisParametersUuid), + this.securityAnalysisParametersUuid, o.securityAnalysisParametersUuid), + new ProcessConfigFieldComparison("loadflowParameters", + Objects.equals(this.loadflowParametersUuid, o.loadflowParametersUuid), + this.loadflowParametersUuid, o.loadflowParametersUuid) + ); + } } diff --git a/monitor-commons/src/test/java/org/gridsuite/monitor/commons/error/MonitorBusinessErrorCodeTest.java b/monitor-commons/src/test/java/org/gridsuite/monitor/commons/error/MonitorBusinessErrorCodeTest.java new file mode 100644 index 00000000..e358f915 --- /dev/null +++ b/monitor-commons/src/test/java/org/gridsuite/monitor/commons/error/MonitorBusinessErrorCodeTest.java @@ -0,0 +1,23 @@ +/** + * Copyright (c) 2026, RTE (http://www.rte-france.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ +package org.gridsuite.monitor.commons.error; + +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.EnumSource; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Franck Lecuyer + */ +class MonitorBusinessErrorCodeTest { + @ParameterizedTest + @EnumSource(MonitorBusinessErrorCode.class) + void valueMatchesEnumName(MonitorBusinessErrorCode code) { + assertThat(code.value()).startsWith("monitor."); + } +} diff --git a/monitor-commons/src/test/java/org/gridsuite/monitor/commons/error/MonitorExceptionHandlerTest.java b/monitor-commons/src/test/java/org/gridsuite/monitor/commons/error/MonitorExceptionHandlerTest.java new file mode 100644 index 00000000..691118d7 --- /dev/null +++ b/monitor-commons/src/test/java/org/gridsuite/monitor/commons/error/MonitorExceptionHandlerTest.java @@ -0,0 +1,40 @@ +/** + * Copyright (c) 2026, RTE (http://www.rte-france.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ +package org.gridsuite.monitor.commons.error; + +import com.powsybl.ws.commons.error.PowsyblWsProblemDetail; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.mock.web.MockHttpServletRequest; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertEquals; + +/** + * @author Franck Lecuyer + */ +class MonitorExceptionHandlerTest { + private MonitorExceptionHandler handler; + + @BeforeEach + void setUp() { + handler = new MonitorExceptionHandler(() -> "monitor-server"); + } + + @Test + void mapsBadRequestBusinessErrorToStatus() { + MockHttpServletRequest request = new MockHttpServletRequest("GET", "/results-endpoint/uuid"); + MonitorException exception = new MonitorException(MonitorBusinessErrorCode.DIFFERENT_PROCESS_CONFIG_TYPE, "Cannot compare different process config types"); + ResponseEntity response = handler.handleMonitorServerException(exception, request); + + assertThat(response.getStatusCode()).isEqualTo(HttpStatus.BAD_REQUEST); + assertThat(response.getBody()).isNotNull(); + assertEquals("monitor.differentProcessConfigType", response.getBody().getBusinessErrorCode()); + } +} diff --git a/monitor-commons/src/test/java/org/gridsuite/monitor/commons/types/processconfig/LoadFlowConfigTest.java b/monitor-commons/src/test/java/org/gridsuite/monitor/commons/types/processconfig/LoadFlowConfigTest.java new file mode 100644 index 00000000..d33803e3 --- /dev/null +++ b/monitor-commons/src/test/java/org/gridsuite/monitor/commons/types/processconfig/LoadFlowConfigTest.java @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2026, RTE (http://www.rte-france.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ +package org.gridsuite.monitor.commons.types.processconfig; + +import org.gridsuite.monitor.commons.error.MonitorException; +import org.gridsuite.monitor.commons.types.processexecution.ProcessType; +import org.junit.jupiter.api.Test; + +import java.util.List; +import java.util.UUID; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.gridsuite.monitor.commons.error.MonitorBusinessErrorCode.DIFFERENT_PROCESS_CONFIG_TYPE; + +/** + * @author Caroline Jeandat {@literal } + */ +class LoadFlowConfigTest { + @Test + void compareWithShouldReturnNoDifferenceWhenConfigsAreEqual() { + LoadFlowConfig processConfig = new LoadFlowConfig(UUID.randomUUID(), List.of(UUID.randomUUID())); + + List result = processConfig.compareWith(processConfig); + + assertThat(result) + .hasSize(2) + .allMatch(ProcessConfigFieldComparison::identical) + .allMatch(fieldComparison -> fieldComparison.value1().equals(fieldComparison.value2())); + } + + @Test + void compareWithShouldReturnDifferentModificationsWhenModificationsAreDifferent() { + UUID loadflowParametersUuid = UUID.randomUUID(); + List modificationUuids1 = List.of(UUID.randomUUID(), UUID.randomUUID()); + List modificationUuids2 = List.of(UUID.randomUUID(), UUID.randomUUID()); + + LoadFlowConfig processConfig1 = new LoadFlowConfig(loadflowParametersUuid, modificationUuids1); + LoadFlowConfig processConfig2 = new LoadFlowConfig(loadflowParametersUuid, modificationUuids2); + + List result = processConfig1.compareWith(processConfig2); + + assertThat(result).hasSize(2); + ProcessConfigFieldComparison comparison = result.stream() + .filter(d -> "modifications".equals(d.field())) + .findFirst() + .orElseThrow(); + assertThat(comparison.identical()).isFalse(); + assertThat(comparison.value1()).isEqualTo(modificationUuids1); + assertThat(comparison.value2()).isEqualTo(modificationUuids2); + } + + @Test + void compareWithShouldDetectOrderDifferenceInModifications() { + UUID loadflowParametersUuid = UUID.randomUUID(); + UUID mod1 = UUID.randomUUID(); + UUID mod2 = UUID.randomUUID(); + List modificationUuids1 = List.of(mod1, mod2); + List modificationUuids2 = List.of(mod2, mod1); // Different order + + LoadFlowConfig processConfig1 = new LoadFlowConfig(loadflowParametersUuid, modificationUuids1); + LoadFlowConfig processConfig2 = new LoadFlowConfig(loadflowParametersUuid, modificationUuids2); + + List result = processConfig1.compareWith(processConfig2); + + assertThat(result).hasSize(2); + ProcessConfigFieldComparison comparison = result.stream() + .filter(d -> "modifications".equals(d.field())) + .findFirst() + .orElseThrow(); + assertThat(comparison.identical()).isFalse(); + assertThat(comparison.value1()).isEqualTo(modificationUuids1); + assertThat(comparison.value2()).isEqualTo(modificationUuids2); + } + + @Test + void compareWithShouldReturnDifferencesWhenParametersAreDifferent() { + UUID loadflowParametersUuid1 = UUID.randomUUID(); + UUID loadflowParametersUuid2 = UUID.randomUUID(); + List modificationUuids = List.of(UUID.randomUUID(), UUID.randomUUID()); + + LoadFlowConfig processConfig1 = new LoadFlowConfig(loadflowParametersUuid1, modificationUuids); + LoadFlowConfig processConfig2 = new LoadFlowConfig(loadflowParametersUuid2, modificationUuids); + + List result = processConfig1.compareWith(processConfig2); + + assertThat(result).hasSize(2); + ProcessConfigFieldComparison comparison = result.stream() + .filter(d -> "loadflowParameters".equals(d.field())) + .findFirst() + .orElseThrow(); + assertThat(comparison.identical()).isFalse(); + assertThat(comparison.value1()).isEqualTo(loadflowParametersUuid1); + assertThat(comparison.value2()).isEqualTo(loadflowParametersUuid2); + } + + @Test + void compareWithShouldThrowWhenProcessTypesAreDifferent() { + LoadFlowConfig loadFlowConfig = new LoadFlowConfig(UUID.randomUUID(), List.of(UUID.randomUUID())); + SecurityAnalysisConfig securityAnalysisConfig = new SecurityAnalysisConfig(UUID.randomUUID(), List.of(UUID.randomUUID()), UUID.randomUUID()); + + assertThatThrownBy(() -> loadFlowConfig.compareWith(securityAnalysisConfig)) + .isInstanceOf(MonitorException.class) + .satisfies(ex -> { + MonitorException e = (MonitorException) ex; + assertThat(e.getErrorCode()).isEqualTo(DIFFERENT_PROCESS_CONFIG_TYPE); + assertThat(e.getBusinessErrorValues()) + .containsEntry("processConfigEntity1Type", ProcessType.LOADFLOW) + .containsEntry("processConfigEntity2Type", ProcessType.SECURITY_ANALYSIS); + }); + } +} diff --git a/monitor-commons/src/test/java/org/gridsuite/monitor/commons/types/processconfig/SecurityAnalysisConfigTest.java b/monitor-commons/src/test/java/org/gridsuite/monitor/commons/types/processconfig/SecurityAnalysisConfigTest.java new file mode 100644 index 00000000..8b52acbe --- /dev/null +++ b/monitor-commons/src/test/java/org/gridsuite/monitor/commons/types/processconfig/SecurityAnalysisConfigTest.java @@ -0,0 +1,141 @@ +/* + * Copyright (c) 2026, RTE (http://www.rte-france.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ +package org.gridsuite.monitor.commons.types.processconfig; + +import org.gridsuite.monitor.commons.error.MonitorException; +import org.gridsuite.monitor.commons.types.processexecution.ProcessType; +import org.junit.jupiter.api.Test; + +import java.util.List; +import java.util.UUID; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.gridsuite.monitor.commons.error.MonitorBusinessErrorCode.DIFFERENT_PROCESS_CONFIG_TYPE; + +/** + * @author Caroline Jeandat {@literal } + */ +class SecurityAnalysisConfigTest { + @Test + void compareWithShouldReturnNoDifferenceWhenConfigsAreEqual() { + SecurityAnalysisConfig securityAnalysisConfig = new SecurityAnalysisConfig(UUID.randomUUID(), List.of(UUID.randomUUID()), UUID.randomUUID()); + + List result = securityAnalysisConfig.compareWith(securityAnalysisConfig); + + assertThat(result) + .hasSize(3) + .allMatch(ProcessConfigFieldComparison::identical) + .allMatch(fieldComparison -> fieldComparison.value1().equals(fieldComparison.value2())); + } + + @Test + void compareWithShouldReturnDifferentModificationsWhenModificationsAreDifferent() { + UUID securityAnalysisParametersUuid = UUID.randomUUID(); + List modificationUuids1 = List.of(UUID.randomUUID(), UUID.randomUUID()); + List modificationUuids2 = List.of(UUID.randomUUID(), UUID.randomUUID()); + UUID loadflowParametersUuid = UUID.randomUUID(); + + SecurityAnalysisConfig processConfig1 = new SecurityAnalysisConfig(securityAnalysisParametersUuid, modificationUuids1, loadflowParametersUuid); + SecurityAnalysisConfig processConfig2 = new SecurityAnalysisConfig(securityAnalysisParametersUuid, modificationUuids2, loadflowParametersUuid); + + List result = processConfig1.compareWith(processConfig2); + + assertThat(result).hasSize(3); + ProcessConfigFieldComparison comparison = result.stream() + .filter(d -> "modifications".equals(d.field())) + .findFirst() + .orElseThrow(); + assertThat(comparison.identical()).isFalse(); + assertThat(comparison.value1()).isEqualTo(modificationUuids1); + assertThat(comparison.value2()).isEqualTo(modificationUuids2); + } + + @Test + void compareWithShouldDetectOrderDifferenceInModifications() { + UUID securityAnalysisParametersUuid = UUID.randomUUID(); + UUID mod1 = UUID.randomUUID(); + UUID mod2 = UUID.randomUUID(); + List modificationUuids1 = List.of(mod1, mod2); + List modificationUuids2 = List.of(mod2, mod1); // Different order + UUID loadflowParametersUuid = UUID.randomUUID(); + + SecurityAnalysisConfig processConfig1 = new SecurityAnalysisConfig(securityAnalysisParametersUuid, modificationUuids1, loadflowParametersUuid); + SecurityAnalysisConfig processConfig2 = new SecurityAnalysisConfig(securityAnalysisParametersUuid, modificationUuids2, loadflowParametersUuid); + + List result = processConfig1.compareWith(processConfig2); + + assertThat(result).hasSize(3); + ProcessConfigFieldComparison comparison = result.stream() + .filter(d -> "modifications".equals(d.field())) + .findFirst() + .orElseThrow(); + assertThat(comparison.identical()).isFalse(); + assertThat(comparison.value1()).isEqualTo(modificationUuids1); + assertThat(comparison.value2()).isEqualTo(modificationUuids2); + } + + @Test + void compareWithShouldReturnDifferencesWhenSecurityAnalysisParametersAreDifferent() { + UUID securityAnalysisParametersUuid1 = UUID.randomUUID(); + UUID securityAnalysisParametersUuid2 = UUID.randomUUID(); + List modificationUuids = List.of(UUID.randomUUID(), UUID.randomUUID()); + UUID loadflowParametersUuid = UUID.randomUUID(); + + SecurityAnalysisConfig processConfig1 = new SecurityAnalysisConfig(securityAnalysisParametersUuid1, modificationUuids, loadflowParametersUuid); + SecurityAnalysisConfig processConfig2 = new SecurityAnalysisConfig(securityAnalysisParametersUuid2, modificationUuids, loadflowParametersUuid); + + List result = processConfig1.compareWith(processConfig2); + + assertThat(result).hasSize(3); + ProcessConfigFieldComparison comparison = result.stream() + .filter(d -> "securityAnalysisParameters".equals(d.field())) + .findFirst() + .orElseThrow(); + assertThat(comparison.identical()).isFalse(); + assertThat(comparison.value1()).isEqualTo(securityAnalysisParametersUuid1); + assertThat(comparison.value2()).isEqualTo(securityAnalysisParametersUuid2); + } + + @Test + void compareWithShouldReturnDifferencesWhenLoadflowParametersAreDifferent() { + UUID securityAnalysisParametersUuid = UUID.randomUUID(); + List modificationUuids = List.of(UUID.randomUUID(), UUID.randomUUID()); + UUID loadflowParametersUuid1 = UUID.randomUUID(); + UUID loadflowParametersUuid2 = UUID.randomUUID(); + + SecurityAnalysisConfig processConfig1 = new SecurityAnalysisConfig(securityAnalysisParametersUuid, modificationUuids, loadflowParametersUuid1); + SecurityAnalysisConfig processConfig2 = new SecurityAnalysisConfig(securityAnalysisParametersUuid, modificationUuids, loadflowParametersUuid2); + + List result = processConfig1.compareWith(processConfig2); + + assertThat(result).hasSize(3); + ProcessConfigFieldComparison comparison = result.stream() + .filter(d -> "loadflowParameters".equals(d.field())) + .findFirst() + .orElseThrow(); + assertThat(comparison.identical()).isFalse(); + assertThat(comparison.value1()).isEqualTo(loadflowParametersUuid1); + assertThat(comparison.value2()).isEqualTo(loadflowParametersUuid2); + } + + @Test + void compareWithShouldThrowWhenProcessTypesAreDifferent() { + SecurityAnalysisConfig securityAnalysisConfig = new SecurityAnalysisConfig(UUID.randomUUID(), List.of(UUID.randomUUID()), UUID.randomUUID()); + LoadFlowConfig loadFlowConfig = new LoadFlowConfig(UUID.randomUUID(), List.of(UUID.randomUUID())); + + assertThatThrownBy(() -> securityAnalysisConfig.compareWith(loadFlowConfig)) + .isInstanceOf(MonitorException.class) + .satisfies(ex -> { + MonitorException e = (MonitorException) ex; + assertThat(e.getErrorCode()).isEqualTo(DIFFERENT_PROCESS_CONFIG_TYPE); + assertThat(e.getBusinessErrorValues()) + .containsEntry("processConfigEntity1Type", ProcessType.SECURITY_ANALYSIS) + .containsEntry("processConfigEntity2Type", ProcessType.LOADFLOW); + }); + } +} diff --git a/monitor-server/src/main/java/org/gridsuite/monitor/server/dto/processconfig/ProcessConfigComparison.java b/monitor-server/src/main/java/org/gridsuite/monitor/server/dto/processconfig/ProcessConfigComparison.java index 0b7fd42b..cf1a657a 100644 --- a/monitor-server/src/main/java/org/gridsuite/monitor/server/dto/processconfig/ProcessConfigComparison.java +++ b/monitor-server/src/main/java/org/gridsuite/monitor/server/dto/processconfig/ProcessConfigComparison.java @@ -7,6 +7,7 @@ package org.gridsuite.monitor.server.dto.processconfig; import io.swagger.v3.oas.annotations.media.Schema; +import org.gridsuite.monitor.commons.types.processconfig.ProcessConfigFieldComparison; import java.util.List; import java.util.UUID; diff --git a/monitor-server/src/main/java/org/gridsuite/monitor/server/error/MonitorServerBusinessErrorCode.java b/monitor-server/src/main/java/org/gridsuite/monitor/server/error/MonitorServerBusinessErrorCode.java index 4315e801..a60a058b 100644 --- a/monitor-server/src/main/java/org/gridsuite/monitor/server/error/MonitorServerBusinessErrorCode.java +++ b/monitor-server/src/main/java/org/gridsuite/monitor/server/error/MonitorServerBusinessErrorCode.java @@ -1,4 +1,4 @@ -/** +/* * Copyright (c) 2026, RTE (http://www.rte-france.com) * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this @@ -12,7 +12,7 @@ * @author Franck Lecuyer */ public enum MonitorServerBusinessErrorCode implements BusinessErrorCode { - DIFFERENT_PROCESS_CONFIG_TYPE("monitor.server.differentProcessConfigType"); + PROCESS_CONFIG_NOT_FOUND("monitor.server.processConfigNotFound"); private final String code; diff --git a/monitor-server/src/main/java/org/gridsuite/monitor/server/error/MonitorServerException.java b/monitor-server/src/main/java/org/gridsuite/monitor/server/error/MonitorServerException.java index af755729..8deaf6dd 100644 --- a/monitor-server/src/main/java/org/gridsuite/monitor/server/error/MonitorServerException.java +++ b/monitor-server/src/main/java/org/gridsuite/monitor/server/error/MonitorServerException.java @@ -1,4 +1,4 @@ -/** +/* * Copyright (c) 2026, RTE (http://www.rte-france.com) * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this diff --git a/monitor-server/src/main/java/org/gridsuite/monitor/server/error/MonitorServerExceptionHandler.java b/monitor-server/src/main/java/org/gridsuite/monitor/server/error/MonitorServerExceptionHandler.java index 05aa2258..83e97989 100644 --- a/monitor-server/src/main/java/org/gridsuite/monitor/server/error/MonitorServerExceptionHandler.java +++ b/monitor-server/src/main/java/org/gridsuite/monitor/server/error/MonitorServerExceptionHandler.java @@ -35,7 +35,7 @@ protected MonitorServerBusinessErrorCode getBusinessCode(MonitorServerException @Override protected HttpStatus mapStatus(MonitorServerBusinessErrorCode errorCode) { return switch (errorCode) { - case DIFFERENT_PROCESS_CONFIG_TYPE -> HttpStatus.BAD_REQUEST; + case PROCESS_CONFIG_NOT_FOUND -> HttpStatus.NOT_FOUND; }; } diff --git a/monitor-server/src/main/java/org/gridsuite/monitor/server/services/processconfig/LoadFlowConfigHandler.java b/monitor-server/src/main/java/org/gridsuite/monitor/server/services/processconfig/LoadFlowConfigHandler.java index b6c5f948..429730c7 100644 --- a/monitor-server/src/main/java/org/gridsuite/monitor/server/services/processconfig/LoadFlowConfigHandler.java +++ b/monitor-server/src/main/java/org/gridsuite/monitor/server/services/processconfig/LoadFlowConfigHandler.java @@ -8,15 +8,10 @@ import org.gridsuite.monitor.commons.types.processconfig.LoadFlowConfig; import org.gridsuite.monitor.commons.types.processexecution.ProcessType; -import org.gridsuite.monitor.server.dto.processconfig.ProcessConfigFieldComparison; import org.gridsuite.monitor.server.entities.processconfig.LoadFlowConfigEntity; import org.gridsuite.monitor.server.mappers.processconfig.LoadFlowConfigMapper; import org.springframework.stereotype.Service; -import java.util.ArrayList; -import java.util.List; -import java.util.Objects; - /** * @author Caroline Jeandat {@literal } */ @@ -31,29 +26,4 @@ public LoadFlowConfigHandler(LoadFlowConfigMapper mapper) { public ProcessType getProcessType() { return ProcessType.LOADFLOW; } - - @Override - public List computeDifferences(LoadFlowConfigEntity entity1, LoadFlowConfigEntity entity2) { - LoadFlowConfig config1 = toProcessConfig(entity1); - LoadFlowConfig config2 = toProcessConfig(entity2); - List differences = new ArrayList<>(); - - // Compare modifications - differences.add(new ProcessConfigFieldComparison( - "modifications", - Objects.equals(config1.modificationUuids(), config2.modificationUuids()), - config1.modificationUuids(), - config2.modificationUuids() - )); - - // Compare loadflow parameters - differences.add(new ProcessConfigFieldComparison( - "loadflowParameters", - Objects.equals(config1.loadflowParametersUuid(), config2.loadflowParametersUuid()), - config1.loadflowParametersUuid(), - config2.loadflowParametersUuid() - )); - - return differences; - } } diff --git a/monitor-server/src/main/java/org/gridsuite/monitor/server/services/processconfig/ProcessConfigHandler.java b/monitor-server/src/main/java/org/gridsuite/monitor/server/services/processconfig/ProcessConfigHandler.java index 34fe58db..458a2563 100644 --- a/monitor-server/src/main/java/org/gridsuite/monitor/server/services/processconfig/ProcessConfigHandler.java +++ b/monitor-server/src/main/java/org/gridsuite/monitor/server/services/processconfig/ProcessConfigHandler.java @@ -8,11 +8,8 @@ import org.gridsuite.monitor.commons.types.processconfig.ProcessConfig; import org.gridsuite.monitor.commons.types.processexecution.ProcessType; -import org.gridsuite.monitor.server.dto.processconfig.ProcessConfigFieldComparison; import org.gridsuite.monitor.server.entities.processconfig.ProcessConfigEntity; -import java.util.List; - /** * @author Caroline Jeandat {@literal } */ @@ -27,6 +24,4 @@ public interface ProcessConfigHandler computeDifferences(E entity1, E entity2); } diff --git a/monitor-server/src/main/java/org/gridsuite/monitor/server/services/processconfig/ProcessConfigService.java b/monitor-server/src/main/java/org/gridsuite/monitor/server/services/processconfig/ProcessConfigService.java index 1942b501..335703a7 100644 --- a/monitor-server/src/main/java/org/gridsuite/monitor/server/services/processconfig/ProcessConfigService.java +++ b/monitor-server/src/main/java/org/gridsuite/monitor/server/services/processconfig/ProcessConfigService.java @@ -10,10 +10,9 @@ import org.gridsuite.monitor.commons.types.processexecution.ProcessType; import org.gridsuite.monitor.server.dto.processconfig.MetadataInfos; import org.gridsuite.monitor.server.dto.processconfig.ProcessConfigComparison; -import org.gridsuite.monitor.server.dto.processconfig.ProcessConfigFieldComparison; +import org.gridsuite.monitor.commons.types.processconfig.ProcessConfigFieldComparison; import org.gridsuite.monitor.server.dto.processconfig.PersistedProcessConfig; import org.gridsuite.monitor.server.entities.processconfig.ProcessConfigEntity; -import org.gridsuite.monitor.server.error.MonitorServerException; import org.gridsuite.monitor.server.repositories.ProcessConfigRepository; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -22,8 +21,6 @@ import java.util.function.Function; import java.util.stream.Collectors; -import static org.gridsuite.monitor.server.error.MonitorServerBusinessErrorCode.DIFFERENT_PROCESS_CONFIG_TYPE; - /** * @author Franck Lecuyer */ @@ -122,12 +119,10 @@ public Optional compareProcessConfigs(UUID uuid1, UUID return Optional.empty(); } - if (processConfigEntity1.get().getProcessType() != processConfigEntity2.get().getProcessType()) { - throw new MonitorServerException(DIFFERENT_PROCESS_CONFIG_TYPE, "Cannot compare different process config types", - Map.of("processConfigEntity1Type", processConfigEntity1.get().getProcessType(), "processConfigEntity2Type", processConfigEntity2.get().getProcessType())); - } + ProcessConfig processConfig1 = getHandler(processConfigEntity1.get().getProcessType()).toProcessConfig(processConfigEntity1.get()); + ProcessConfig processConfig2 = getHandler(processConfigEntity2.get().getProcessType()).toProcessConfig(processConfigEntity2.get()); - List differences = getHandler(processConfigEntity1.get().getProcessType()).computeDifferences(processConfigEntity1.get(), processConfigEntity2.get()); + List differences = processConfig1.compareWith(processConfig2); boolean identical = differences.stream().allMatch(ProcessConfigFieldComparison::identical); return Optional.of(new ProcessConfigComparison(uuid1, uuid2, identical, differences)); diff --git a/monitor-server/src/main/java/org/gridsuite/monitor/server/services/processconfig/SecurityAnalysisConfigHandler.java b/monitor-server/src/main/java/org/gridsuite/monitor/server/services/processconfig/SecurityAnalysisConfigHandler.java index 5bfb0107..1e20dbe5 100644 --- a/monitor-server/src/main/java/org/gridsuite/monitor/server/services/processconfig/SecurityAnalysisConfigHandler.java +++ b/monitor-server/src/main/java/org/gridsuite/monitor/server/services/processconfig/SecurityAnalysisConfigHandler.java @@ -8,15 +8,10 @@ import org.gridsuite.monitor.commons.types.processconfig.SecurityAnalysisConfig; import org.gridsuite.monitor.commons.types.processexecution.ProcessType; -import org.gridsuite.monitor.server.dto.processconfig.ProcessConfigFieldComparison; import org.gridsuite.monitor.server.entities.processconfig.SecurityAnalysisConfigEntity; import org.gridsuite.monitor.server.mappers.processconfig.SecurityAnalysisConfigMapper; import org.springframework.stereotype.Service; -import java.util.ArrayList; -import java.util.List; -import java.util.Objects; - /** * @author Caroline Jeandat {@literal } */ @@ -31,38 +26,4 @@ public SecurityAnalysisConfigHandler(SecurityAnalysisConfigMapper mapper) { public ProcessType getProcessType() { return ProcessType.SECURITY_ANALYSIS; } - - @Override - public List computeDifferences(SecurityAnalysisConfigEntity entity1, SecurityAnalysisConfigEntity entity2) { - // error si pas bon processType - SecurityAnalysisConfig config1 = toProcessConfig(entity1); - SecurityAnalysisConfig config2 = toProcessConfig(entity2); - List differences = new ArrayList<>(); - - // Compare modifications - differences.add(new ProcessConfigFieldComparison( - "modifications", - Objects.equals(config1.modificationUuids(), config2.modificationUuids()), - config1.modificationUuids(), - config2.modificationUuids() - )); - - // Compare loadflow parameters - differences.add(new ProcessConfigFieldComparison( - "loadflowParameters", - Objects.equals(config1.loadflowParametersUuid(), config2.loadflowParametersUuid()), - config1.loadflowParametersUuid(), - config2.loadflowParametersUuid() - )); - - // Compare security analysis parameters - differences.add(new ProcessConfigFieldComparison( - "securityAnalysisParameters", - Objects.equals(config1.securityAnalysisParametersUuid(), config2.securityAnalysisParametersUuid()), - config1.securityAnalysisParametersUuid(), - config2.securityAnalysisParametersUuid() - )); - - return differences; - } } diff --git a/monitor-server/src/test/java/org/gridsuite/monitor/server/controllers/ProcessConfigControllerTest.java b/monitor-server/src/test/java/org/gridsuite/monitor/server/controllers/ProcessConfigControllerTest.java index 848f320e..b8e5baca 100644 --- a/monitor-server/src/test/java/org/gridsuite/monitor/server/controllers/ProcessConfigControllerTest.java +++ b/monitor-server/src/test/java/org/gridsuite/monitor/server/controllers/ProcessConfigControllerTest.java @@ -7,6 +7,7 @@ package org.gridsuite.monitor.server.controllers; import com.fasterxml.jackson.databind.ObjectMapper; +import org.gridsuite.monitor.commons.error.MonitorExceptionHandler; import org.gridsuite.monitor.server.PropertyServerNameProvider; import org.gridsuite.monitor.server.dto.processconfig.MetadataInfos; import org.gridsuite.monitor.server.dto.processconfig.PersistedProcessConfig; @@ -14,12 +15,13 @@ import org.gridsuite.monitor.commons.types.processconfig.SecurityAnalysisConfig; import org.gridsuite.monitor.commons.types.processexecution.ProcessType; import org.gridsuite.monitor.server.dto.processconfig.ProcessConfigComparison; -import org.gridsuite.monitor.server.dto.processconfig.ProcessConfigFieldComparison; -import org.gridsuite.monitor.server.error.MonitorServerException; +import org.gridsuite.monitor.commons.types.processconfig.ProcessConfigFieldComparison; +import org.gridsuite.monitor.commons.error.MonitorException; import org.gridsuite.monitor.server.services.processconfig.ProcessConfigService; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; +import org.springframework.context.annotation.Import; import org.springframework.http.MediaType; import org.springframework.test.context.bean.override.mockito.MockitoBean; import org.springframework.test.web.servlet.MockMvc; @@ -28,7 +30,7 @@ import java.util.Optional; import java.util.UUID; -import static org.gridsuite.monitor.server.error.MonitorServerBusinessErrorCode.DIFFERENT_PROCESS_CONFIG_TYPE; +import static org.gridsuite.monitor.commons.error.MonitorBusinessErrorCode.DIFFERENT_PROCESS_CONFIG_TYPE; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -44,6 +46,7 @@ * @author Franck Lecuyer */ @WebMvcTest(controllers = { ProcessConfigController.class, PropertyServerNameProvider.class }) +@Import(MonitorExceptionHandler.class) class ProcessConfigControllerTest { @Autowired @@ -343,7 +346,7 @@ void compareProcessConfigsShouldReturn400WhenDifferentTypes() throws Exception { UUID uuid2 = UUID.randomUUID(); when(processConfigService.compareProcessConfigs(any(), any())) - .thenThrow(new MonitorServerException(DIFFERENT_PROCESS_CONFIG_TYPE, "Cannot compare different process config types")); + .thenThrow(new MonitorException(DIFFERENT_PROCESS_CONFIG_TYPE, "Cannot compare different process config types")); mockMvc.perform(get("/v1/process-configs/compare") .param("uuid1", uuid1.toString()) diff --git a/monitor-server/src/test/java/org/gridsuite/monitor/server/error/MonitorServerExceptionHandlerTest.java b/monitor-server/src/test/java/org/gridsuite/monitor/server/error/MonitorServerExceptionHandlerTest.java index d507307c..fe911d4a 100644 --- a/monitor-server/src/test/java/org/gridsuite/monitor/server/error/MonitorServerExceptionHandlerTest.java +++ b/monitor-server/src/test/java/org/gridsuite/monitor/server/error/MonitorServerExceptionHandlerTest.java @@ -14,7 +14,6 @@ import org.springframework.mock.web.MockHttpServletRequest; import static org.assertj.core.api.Assertions.assertThat; -import static org.gridsuite.monitor.server.error.MonitorServerBusinessErrorCode.DIFFERENT_PROCESS_CONFIG_TYPE; import static org.junit.jupiter.api.Assertions.assertEquals; /** @@ -31,11 +30,11 @@ void setUp() { @Test void mapsBadRequestBusinessErrorToStatus() { MockHttpServletRequest request = new MockHttpServletRequest("GET", "/results-endpoint/uuid"); - MonitorServerException exception = new MonitorServerException(DIFFERENT_PROCESS_CONFIG_TYPE, "Cannot compare different process config types"); + MonitorServerException exception = new MonitorServerException(MonitorServerBusinessErrorCode.PROCESS_CONFIG_NOT_FOUND, "Process config not found"); ResponseEntity response = handler.handleMonitorServerException(exception, request); - assertThat(response.getStatusCode()).isEqualTo(HttpStatus.BAD_REQUEST); + assertThat(response.getStatusCode()).isEqualTo(HttpStatus.NOT_FOUND); assertThat(response.getBody()).isNotNull(); - assertEquals("monitor.server.differentProcessConfigType", response.getBody().getBusinessErrorCode()); + assertEquals("monitor.server.processConfigNotFound", response.getBody().getBusinessErrorCode()); } } diff --git a/monitor-server/src/test/java/org/gridsuite/monitor/server/services/processconfig/LoadFlowConfigHandlerTest.java b/monitor-server/src/test/java/org/gridsuite/monitor/server/services/processconfig/LoadFlowConfigHandlerTest.java index 60075b6b..d2f8695f 100644 --- a/monitor-server/src/test/java/org/gridsuite/monitor/server/services/processconfig/LoadFlowConfigHandlerTest.java +++ b/monitor-server/src/test/java/org/gridsuite/monitor/server/services/processconfig/LoadFlowConfigHandlerTest.java @@ -9,11 +9,9 @@ import org.gridsuite.monitor.commons.types.processconfig.LoadFlowConfig; import org.gridsuite.monitor.commons.types.processexecution.ProcessType; -import org.gridsuite.monitor.server.dto.processconfig.ProcessConfigFieldComparison; import org.gridsuite.monitor.server.entities.processconfig.LoadFlowConfigEntity; import org.gridsuite.monitor.server.mappers.processconfig.LoadFlowConfigMapper; import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mapstruct.factory.Mappers; import org.mockito.Mockito; @@ -22,10 +20,6 @@ import java.util.List; import java.util.UUID; -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - /** * @author Caroline Jeandat {@literal } */ @@ -53,110 +47,4 @@ protected void setUp() { mapper = Mockito.spy(realMapper); handler = new LoadFlowConfigHandler(mapper); } - - @Test - void computeDifferencesShouldReturnNoDifferenceWhenConfigsAreEqual() { - LoadFlowConfig processConfig = createProcessConfig(); - LoadFlowConfigEntity entity1 = createProcessConfigEntity(); - LoadFlowConfigEntity entity2 = createProcessConfigEntity(); - - when(mapper.toDto(entity1)).thenReturn(processConfig); - when(mapper.toDto(entity2)).thenReturn(processConfig); - - List result = handler.computeDifferences(entity1, entity2); - - assertThat(result) - .hasSize(2) - .allMatch(ProcessConfigFieldComparison::identical) - .allMatch(fieldComparison -> fieldComparison.value1().equals(fieldComparison.value2())); - } - - @Test - void computeDifferencesShouldReturnDifferentModificationsWhenModificationsAreDifferent() { - UUID loadflowParametersUuid = UUID.randomUUID(); - List modificationUuids1 = List.of(UUID.randomUUID(), UUID.randomUUID()); - List modificationUuids2 = List.of(UUID.randomUUID(), UUID.randomUUID()); - - LoadFlowConfig processConfig1 = new LoadFlowConfig(loadflowParametersUuid, modificationUuids1); - LoadFlowConfig processConfig2 = new LoadFlowConfig(loadflowParametersUuid, modificationUuids2); - - LoadFlowConfigEntity entity1 = Mockito.mock(LoadFlowConfigEntity.class); - LoadFlowConfigEntity entity2 = Mockito.mock(LoadFlowConfigEntity.class); - - when(mapper.toDto(entity1)).thenReturn(processConfig1); - when(mapper.toDto(entity2)).thenReturn(processConfig2); - - List result = handler.computeDifferences(entity1, entity2); - - assertThat(result).hasSize(2); - ProcessConfigFieldComparison comparison = result.stream() - .filter(d -> "modifications".equals(d.field())) - .findFirst() - .orElseThrow(); - assertThat(comparison.identical()).isFalse(); - assertThat(comparison.value1()).isEqualTo(modificationUuids1); - assertThat(comparison.value2()).isEqualTo(modificationUuids2); - verify(mapper).toDto(entity1); - verify(mapper).toDto(entity2); - } - - @Test - void computeDifferencesShouldDetectOrderDifferenceInModifications() { - UUID loadflowParametersUuid = UUID.randomUUID(); - UUID mod1 = UUID.randomUUID(); - UUID mod2 = UUID.randomUUID(); - List modificationUuids1 = List.of(mod1, mod2); - List modificationUuids2 = List.of(mod2, mod1); // Different order - - LoadFlowConfig processConfig1 = new LoadFlowConfig(loadflowParametersUuid, modificationUuids1); - LoadFlowConfig processConfig2 = new LoadFlowConfig(loadflowParametersUuid, modificationUuids2); - - LoadFlowConfigEntity entity1 = Mockito.mock(LoadFlowConfigEntity.class); - LoadFlowConfigEntity entity2 = Mockito.mock(LoadFlowConfigEntity.class); - - when(mapper.toDto(entity1)).thenReturn(processConfig1); - when(mapper.toDto(entity2)).thenReturn(processConfig2); - - List result = handler.computeDifferences(entity1, entity2); - - assertThat(result).hasSize(2); - ProcessConfigFieldComparison comparison = result.stream() - .filter(d -> "modifications".equals(d.field())) - .findFirst() - .orElseThrow(); - assertThat(comparison.identical()).isFalse(); - assertThat(comparison.value1()).isEqualTo(modificationUuids1); - assertThat(comparison.value2()).isEqualTo(modificationUuids2); - verify(mapper).toDto(entity1); - verify(mapper).toDto(entity2); - } - - @Test - void computeDifferencesShouldReturnDifferencesWhenParametersAreDifferent() { - UUID loadflowParametersUuid1 = UUID.randomUUID(); - UUID loadflowParametersUuid2 = UUID.randomUUID(); - List modificationUuids = List.of(UUID.randomUUID(), UUID.randomUUID()); - - LoadFlowConfig processConfig1 = new LoadFlowConfig(loadflowParametersUuid1, modificationUuids); - LoadFlowConfig processConfig2 = new LoadFlowConfig(loadflowParametersUuid2, modificationUuids); - - LoadFlowConfigEntity entity1 = Mockito.mock(LoadFlowConfigEntity.class); - LoadFlowConfigEntity entity2 = Mockito.mock(LoadFlowConfigEntity.class); - - when(mapper.toDto(entity1)).thenReturn(processConfig1); - when(mapper.toDto(entity2)).thenReturn(processConfig2); - - List result = handler.computeDifferences(entity1, entity2); - - assertThat(result).hasSize(2); - ProcessConfigFieldComparison comparison = result.stream() - .filter(d -> "loadflowParameters".equals(d.field())) - .findFirst() - .orElseThrow(); - assertThat(comparison.identical()).isFalse(); - assertThat(comparison.value1()).isEqualTo(loadflowParametersUuid1); - assertThat(comparison.value2()).isEqualTo(loadflowParametersUuid2); - verify(mapper).toDto(entity1); - verify(mapper).toDto(entity2); - } } diff --git a/monitor-server/src/test/java/org/gridsuite/monitor/server/services/processconfig/ProcessConfigServiceTest.java b/monitor-server/src/test/java/org/gridsuite/monitor/server/services/processconfig/ProcessConfigServiceTest.java index 2c09eab9..c7807e86 100644 --- a/monitor-server/src/test/java/org/gridsuite/monitor/server/services/processconfig/ProcessConfigServiceTest.java +++ b/monitor-server/src/test/java/org/gridsuite/monitor/server/services/processconfig/ProcessConfigServiceTest.java @@ -6,16 +6,18 @@ */ package org.gridsuite.monitor.server.services.processconfig; +import org.gridsuite.monitor.commons.types.processconfig.LoadFlowConfig; import org.gridsuite.monitor.commons.types.processconfig.ProcessConfig; +import org.gridsuite.monitor.commons.types.processconfig.SecurityAnalysisConfig; import org.gridsuite.monitor.commons.types.processexecution.ProcessType; import org.gridsuite.monitor.server.dto.processconfig.MetadataInfos; import org.gridsuite.monitor.server.dto.processconfig.PersistedProcessConfig; import org.gridsuite.monitor.server.dto.processconfig.ProcessConfigComparison; -import org.gridsuite.monitor.server.dto.processconfig.ProcessConfigFieldComparison; +import org.gridsuite.monitor.commons.types.processconfig.ProcessConfigFieldComparison; import org.gridsuite.monitor.server.entities.processconfig.LoadFlowConfigEntity; import org.gridsuite.monitor.server.entities.processconfig.ProcessConfigEntity; import org.gridsuite.monitor.server.entities.processconfig.SecurityAnalysisConfigEntity; -import org.gridsuite.monitor.server.error.MonitorServerException; +import org.gridsuite.monitor.commons.error.MonitorException; import org.gridsuite.monitor.server.repositories.ProcessConfigRepository; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -27,7 +29,7 @@ import java.util.*; import static org.assertj.core.api.Assertions.*; -import static org.gridsuite.monitor.server.error.MonitorServerBusinessErrorCode.DIFFERENT_PROCESS_CONFIG_TYPE; +import static org.gridsuite.monitor.commons.error.MonitorBusinessErrorCode.DIFFERENT_PROCESS_CONFIG_TYPE; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.*; @@ -264,7 +266,8 @@ void compareProcessConfigsWithEqualProcessConfigs() { when(processConfigRepository.findById(processConfigUuid1)).thenReturn(Optional.of(processConfigEntity)); when(processConfigRepository.findById(processConfigUuid2)).thenReturn(Optional.of(processConfigEntity)); when(processConfigEntity.getProcessType()).thenReturn(PROCESS_TYPE); - when(handler.computeDifferences(processConfigEntity, processConfigEntity)).thenReturn(List.of(fieldComparison)); + when(handler.toProcessConfig(processConfigEntity)).thenReturn(processConfig); + when(processConfig.compareWith(processConfig)).thenReturn(List.of(fieldComparison)); Optional result = processConfigService.compareProcessConfigs(processConfigUuid1, processConfigUuid2); @@ -273,7 +276,8 @@ void compareProcessConfigsWithEqualProcessConfigs() { .contains(new ProcessConfigComparison(processConfigUuid1, processConfigUuid2, true, List.of(fieldComparison))); verify(processConfigRepository).findById(processConfigUuid1); verify(processConfigRepository).findById(processConfigUuid2); - verify(handler).computeDifferences(processConfigEntity, processConfigEntity); + verify(handler, times(2)).toProcessConfig(processConfigEntity); + verify(processConfig).compareWith(processConfig); } @Test @@ -282,13 +286,17 @@ void compareProcessConfigsWithDifferentProcessConfigs() { UUID processConfigUuid2 = UUID.randomUUID(); ProcessConfigEntity processConfigEntity1 = Mockito.mock(ProcessConfigEntity.class); ProcessConfigEntity processConfigEntity2 = Mockito.mock(ProcessConfigEntity.class); + ProcessConfig processConfig1 = Mockito.mock(ProcessConfig.class); + ProcessConfig processConfig2 = Mockito.mock(ProcessConfig.class); ProcessConfigFieldComparison fieldComparison = new ProcessConfigFieldComparison("field", false, "value1", "value2"); when(processConfigRepository.findById(processConfigUuid1)).thenReturn(Optional.of(processConfigEntity1)); when(processConfigRepository.findById(processConfigUuid2)).thenReturn(Optional.of(processConfigEntity2)); when(processConfigEntity1.getProcessType()).thenReturn(PROCESS_TYPE); when(processConfigEntity2.getProcessType()).thenReturn(PROCESS_TYPE); - when(handler.computeDifferences(processConfigEntity1, processConfigEntity2)).thenReturn(List.of(fieldComparison)); + when(handler.toProcessConfig(processConfigEntity1)).thenReturn(processConfig1); + when(handler.toProcessConfig(processConfigEntity2)).thenReturn(processConfig2); + when(processConfig1.compareWith(processConfig2)).thenReturn(List.of(fieldComparison)); Optional result = processConfigService.compareProcessConfigs(processConfigUuid1, processConfigUuid2); @@ -297,7 +305,9 @@ void compareProcessConfigsWithDifferentProcessConfigs() { .contains(new ProcessConfigComparison(processConfigUuid1, processConfigUuid2, false, List.of(fieldComparison))); verify(processConfigRepository).findById(processConfigUuid1); verify(processConfigRepository).findById(processConfigUuid2); - verify(handler).computeDifferences(processConfigEntity1, processConfigEntity2); + verify(handler).toProcessConfig(processConfigEntity1); + verify(handler).toProcessConfig(processConfigEntity2); + verify(processConfig1).compareWith(processConfig2); } @Test @@ -312,7 +322,7 @@ void compareProcessConfigWithFirstProcessConfigNotFound() { assertThat(result).isEmpty(); verify(processConfigRepository).findById(processConfigUuid1); - verify(handler, never()).computeDifferences(any(), any()); + verify(handler, never()).toProcessConfig(any()); } @Test @@ -331,32 +341,45 @@ void compareProcessConfigWithSecondProcessConfigNotFound() { assertThat(result).isEmpty(); verify(processConfigRepository).findById(processConfigUuid1); verify(processConfigRepository).findById(processConfigUuid2); - verify(handler, never()).computeDifferences(any(), any()); + verify(handler, never()).toProcessConfig(any()); } @Test void compareProcessConfigsShouldThrowWhenProcessTypesAreDifferent() { UUID processConfigUuid1 = UUID.randomUUID(); UUID processConfigUuid2 = UUID.randomUUID(); - ProcessConfigEntity processConfigEntity1 = Mockito.mock(ProcessConfigEntity.class); - ProcessConfigEntity processConfigEntity2 = Mockito.mock(ProcessConfigEntity.class); + ProcessConfigEntity processConfigEntity1 = Mockito.mock(SecurityAnalysisConfigEntity.class); + ProcessConfigEntity processConfigEntity2 = Mockito.mock(LoadFlowConfigEntity.class); + ProcessConfig processConfig1 = Mockito.mock(SecurityAnalysisConfig.class); + ProcessConfig processConfig2 = Mockito.mock(LoadFlowConfig.class); + ProcessConfigHandler handler2 = Mockito.mock(ProcessConfigHandler.class); + + when(handler2.getProcessType()).thenReturn(ProcessType.LOADFLOW); + + processConfigService = new ProcessConfigService( + processConfigRepository, + List.of(handler, handler2) + ); when(processConfigRepository.findById(processConfigUuid1)).thenReturn(Optional.of(processConfigEntity1)); when(processConfigRepository.findById(processConfigUuid2)).thenReturn(Optional.of(processConfigEntity2)); - when(processConfigEntity1.getProcessType()).thenReturn(ProcessType.LOADFLOW); - when(processConfigEntity2.getProcessType()).thenReturn(ProcessType.SECURITY_ANALYSIS); + when(processConfigEntity1.getProcessType()).thenReturn(ProcessType.SECURITY_ANALYSIS); + when(handler.toProcessConfig(processConfigEntity1)).thenReturn(processConfig1); + when(processConfigEntity2.getProcessType()).thenReturn(ProcessType.LOADFLOW); + when(handler2.toProcessConfig(processConfigEntity2)).thenReturn(processConfig2); + when(processConfig1.compareWith(processConfig2)) + .thenThrow(new MonitorException(DIFFERENT_PROCESS_CONFIG_TYPE, "Cannot compare different process config types")); assertThatThrownBy(() -> processConfigService.compareProcessConfigs(processConfigUuid1, processConfigUuid2)) - .isInstanceOf(MonitorServerException.class) + .isInstanceOf(MonitorException.class) .satisfies(ex -> { - MonitorServerException e = (MonitorServerException) ex; + MonitorException e = (MonitorException) ex; assertThat(e.getErrorCode()).isEqualTo(DIFFERENT_PROCESS_CONFIG_TYPE); - assertThat(e.getBusinessErrorValues()) - .containsEntry("processConfigEntity1Type", ProcessType.LOADFLOW) - .containsEntry("processConfigEntity2Type", ProcessType.SECURITY_ANALYSIS); }); verify(processConfigRepository).findById(processConfigUuid1); verify(processConfigRepository).findById(processConfigUuid2); - verify(handler, never()).computeDifferences(any(), any()); + verify(handler).toProcessConfig(processConfigEntity1); + verify(handler2).toProcessConfig(processConfigEntity2); + verify(processConfig1).compareWith(processConfig2); } } diff --git a/monitor-server/src/test/java/org/gridsuite/monitor/server/services/processconfig/SecurityAnalysisConfigHandlerTest.java b/monitor-server/src/test/java/org/gridsuite/monitor/server/services/processconfig/SecurityAnalysisConfigHandlerTest.java index 161ed703..08de5f42 100644 --- a/monitor-server/src/test/java/org/gridsuite/monitor/server/services/processconfig/SecurityAnalysisConfigHandlerTest.java +++ b/monitor-server/src/test/java/org/gridsuite/monitor/server/services/processconfig/SecurityAnalysisConfigHandlerTest.java @@ -8,11 +8,9 @@ import org.gridsuite.monitor.commons.types.processconfig.SecurityAnalysisConfig; import org.gridsuite.monitor.commons.types.processexecution.ProcessType; -import org.gridsuite.monitor.server.dto.processconfig.ProcessConfigFieldComparison; import org.gridsuite.monitor.server.entities.processconfig.SecurityAnalysisConfigEntity; import org.gridsuite.monitor.server.mappers.processconfig.SecurityAnalysisConfigMapper; import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mapstruct.factory.Mappers; import org.mockito.Mockito; @@ -21,10 +19,6 @@ import java.util.List; import java.util.UUID; -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - /** * @author Caroline Jeandat {@literal } */ @@ -52,143 +46,4 @@ protected void setUp() { mapper = Mockito.spy(realMapper); handler = new SecurityAnalysisConfigHandler(mapper); } - - @Test - void computeDifferencesShouldReturnNoDifferenceWhenConfigsAreEqual() { - SecurityAnalysisConfig processConfig = createProcessConfig(); - SecurityAnalysisConfigEntity entity1 = createProcessConfigEntity(); - SecurityAnalysisConfigEntity entity2 = createProcessConfigEntity(); - - when(mapper.toDto(entity1)).thenReturn(processConfig); - when(mapper.toDto(entity2)).thenReturn(processConfig); - - List result = handler.computeDifferences(entity1, entity2); - - assertThat(result) - .hasSize(3) - .allMatch(ProcessConfigFieldComparison::identical) - .allMatch(fieldComparison -> fieldComparison.value1().equals(fieldComparison.value2())); - } - - @Test - void computeDifferencesShouldReturnDifferentModificationsWhenModificationsAreDifferent() { - UUID securityAnalysisParametersUuid = UUID.randomUUID(); - List modificationUuids1 = List.of(UUID.randomUUID(), UUID.randomUUID()); - List modificationUuids2 = List.of(UUID.randomUUID(), UUID.randomUUID()); - UUID loadflowParametersUuid = UUID.randomUUID(); - - SecurityAnalysisConfig processConfig1 = new SecurityAnalysisConfig(securityAnalysisParametersUuid, modificationUuids1, loadflowParametersUuid); - SecurityAnalysisConfig processConfig2 = new SecurityAnalysisConfig(securityAnalysisParametersUuid, modificationUuids2, loadflowParametersUuid); - - SecurityAnalysisConfigEntity entity1 = Mockito.mock(SecurityAnalysisConfigEntity.class); - SecurityAnalysisConfigEntity entity2 = Mockito.mock(SecurityAnalysisConfigEntity.class); - - when(mapper.toDto(entity1)).thenReturn(processConfig1); - when(mapper.toDto(entity2)).thenReturn(processConfig2); - - List result = handler.computeDifferences(entity1, entity2); - - assertThat(result).hasSize(3); - ProcessConfigFieldComparison comparison = result.stream() - .filter(d -> "modifications".equals(d.field())) - .findFirst() - .orElseThrow(); - assertThat(comparison.identical()).isFalse(); - assertThat(comparison.value1()).isEqualTo(modificationUuids1); - assertThat(comparison.value2()).isEqualTo(modificationUuids2); - verify(mapper).toDto(entity1); - verify(mapper).toDto(entity2); - } - - @Test - void computeDifferencesShouldDetectOrderDifferenceInModifications() { - UUID securityAnalysisParametersUuid = UUID.randomUUID(); - UUID mod1 = UUID.randomUUID(); - UUID mod2 = UUID.randomUUID(); - List modificationUuids1 = List.of(mod1, mod2); - List modificationUuids2 = List.of(mod2, mod1); // Different order - UUID loadflowParametersUuid = UUID.randomUUID(); - - SecurityAnalysisConfig processConfig1 = new SecurityAnalysisConfig(securityAnalysisParametersUuid, modificationUuids1, loadflowParametersUuid); - SecurityAnalysisConfig processConfig2 = new SecurityAnalysisConfig(securityAnalysisParametersUuid, modificationUuids2, loadflowParametersUuid); - - SecurityAnalysisConfigEntity entity1 = Mockito.mock(SecurityAnalysisConfigEntity.class); - SecurityAnalysisConfigEntity entity2 = Mockito.mock(SecurityAnalysisConfigEntity.class); - - when(mapper.toDto(entity1)).thenReturn(processConfig1); - when(mapper.toDto(entity2)).thenReturn(processConfig2); - - List result = handler.computeDifferences(entity1, entity2); - - assertThat(result).hasSize(3); - ProcessConfigFieldComparison comparison = result.stream() - .filter(d -> "modifications".equals(d.field())) - .findFirst() - .orElseThrow(); - assertThat(comparison.identical()).isFalse(); - assertThat(comparison.value1()).isEqualTo(modificationUuids1); - assertThat(comparison.value2()).isEqualTo(modificationUuids2); - verify(mapper).toDto(entity1); - verify(mapper).toDto(entity2); - } - - @Test - void computeDifferencesShouldReturnDifferencesWhenSecurityAnalysisParametersAreDifferent() { - UUID securityAnalysisParametersUuid1 = UUID.randomUUID(); - UUID securityAnalysisParametersUuid2 = UUID.randomUUID(); - List modificationUuids = List.of(UUID.randomUUID(), UUID.randomUUID()); - UUID loadflowParametersUuid = UUID.randomUUID(); - - SecurityAnalysisConfig processConfig1 = new SecurityAnalysisConfig(securityAnalysisParametersUuid1, modificationUuids, loadflowParametersUuid); - SecurityAnalysisConfig processConfig2 = new SecurityAnalysisConfig(securityAnalysisParametersUuid2, modificationUuids, loadflowParametersUuid); - - SecurityAnalysisConfigEntity entity1 = Mockito.mock(SecurityAnalysisConfigEntity.class); - SecurityAnalysisConfigEntity entity2 = Mockito.mock(SecurityAnalysisConfigEntity.class); - - when(mapper.toDto(entity1)).thenReturn(processConfig1); - when(mapper.toDto(entity2)).thenReturn(processConfig2); - - List result = handler.computeDifferences(entity1, entity2); - - assertThat(result).hasSize(3); - ProcessConfigFieldComparison comparison = result.stream() - .filter(d -> "securityAnalysisParameters".equals(d.field())) - .findFirst() - .orElseThrow(); - assertThat(comparison.identical()).isFalse(); - assertThat(comparison.value1()).isEqualTo(securityAnalysisParametersUuid1); - assertThat(comparison.value2()).isEqualTo(securityAnalysisParametersUuid2); - verify(mapper).toDto(entity1); - verify(mapper).toDto(entity2); - } - - @Test - void computeDifferencesShouldReturnDifferencesWhenLoadflowParametersAreDifferent() { - UUID securityAnalysisParametersUuid = UUID.randomUUID(); - List modificationUuids = List.of(UUID.randomUUID(), UUID.randomUUID()); - UUID loadflowParametersUuid1 = UUID.randomUUID(); - UUID loadflowParametersUuid2 = UUID.randomUUID(); - - SecurityAnalysisConfig processConfig1 = new SecurityAnalysisConfig(securityAnalysisParametersUuid, modificationUuids, loadflowParametersUuid1); - SecurityAnalysisConfig processConfig2 = new SecurityAnalysisConfig(securityAnalysisParametersUuid, modificationUuids, loadflowParametersUuid2); - - SecurityAnalysisConfigEntity entity1 = Mockito.mock(SecurityAnalysisConfigEntity.class); - SecurityAnalysisConfigEntity entity2 = Mockito.mock(SecurityAnalysisConfigEntity.class); - - when(mapper.toDto(entity1)).thenReturn(processConfig1); - when(mapper.toDto(entity2)).thenReturn(processConfig2); - - List result = handler.computeDifferences(entity1, entity2); - - assertThat(result).hasSize(3); - ProcessConfigFieldComparison comparison = result.stream() - .filter(d -> "loadflowParameters".equals(d.field())) - .findFirst() - .orElseThrow(); - assertThat(comparison.identical()).isFalse(); - assertThat(comparison.value1()).isEqualTo(loadflowParametersUuid1); - assertThat(comparison.value2()).isEqualTo(loadflowParametersUuid2); - verify(mapper).toDto(entity1); - verify(mapper).toDto(entity2); - } } From bd760ea0e0007e725764e63fccab6b487cfe7885 Mon Sep 17 00:00:00 2001 From: Caroline Jeandat Date: Thu, 25 Jun 2026 17:12:49 +0200 Subject: [PATCH 5/9] remove businessCodeError for process type mismatch Signed-off-by: Caroline Jeandat --- monitor-commons/pom.xml | 4 -- .../error/MonitorBusinessErrorCode.java | 26 ---------- .../commons/error/MonitorException.java | 46 ------------------ .../error/MonitorExceptionHandler.java | 47 ------------------- .../types/processconfig/LoadFlowConfig.java | 9 +--- .../processconfig/SecurityAnalysisConfig.java | 9 +--- .../error/MonitorBusinessErrorCodeTest.java | 23 --------- .../error/MonitorExceptionHandlerTest.java | 40 ---------------- .../processconfig/LoadFlowConfigTest.java | 13 +---- .../SecurityAnalysisConfigTest.java | 13 +---- .../controllers/ProcessConfigController.java | 8 +++- .../ProcessConfigControllerTest.java | 7 +-- .../ProcessConfigServiceTest.java | 10 +--- 13 files changed, 13 insertions(+), 242 deletions(-) delete mode 100644 monitor-commons/src/main/java/org/gridsuite/monitor/commons/error/MonitorBusinessErrorCode.java delete mode 100644 monitor-commons/src/main/java/org/gridsuite/monitor/commons/error/MonitorException.java delete mode 100644 monitor-commons/src/main/java/org/gridsuite/monitor/commons/error/MonitorExceptionHandler.java delete mode 100644 monitor-commons/src/test/java/org/gridsuite/monitor/commons/error/MonitorBusinessErrorCodeTest.java delete mode 100644 monitor-commons/src/test/java/org/gridsuite/monitor/commons/error/MonitorExceptionHandlerTest.java diff --git a/monitor-commons/pom.xml b/monitor-commons/pom.xml index 85efcf14..ade2437d 100644 --- a/monitor-commons/pom.xml +++ b/monitor-commons/pom.xml @@ -33,10 +33,6 @@ 2.2.22 provided - - com.powsybl - powsybl-ws-commons - org.junit.jupiter junit-jupiter-params diff --git a/monitor-commons/src/main/java/org/gridsuite/monitor/commons/error/MonitorBusinessErrorCode.java b/monitor-commons/src/main/java/org/gridsuite/monitor/commons/error/MonitorBusinessErrorCode.java deleted file mode 100644 index cc4b2c31..00000000 --- a/monitor-commons/src/main/java/org/gridsuite/monitor/commons/error/MonitorBusinessErrorCode.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright (c) 2026, RTE (http://www.rte-france.com) - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - */ -package org.gridsuite.monitor.commons.error; - -import com.powsybl.ws.commons.error.BusinessErrorCode; - -/** - * @author Franck Lecuyer - */ -public enum MonitorBusinessErrorCode implements BusinessErrorCode { - DIFFERENT_PROCESS_CONFIG_TYPE("monitor.differentProcessConfigType"); - - private final String code; - - MonitorBusinessErrorCode(String code) { - this.code = code; - } - - public String value() { - return code; - } -} diff --git a/monitor-commons/src/main/java/org/gridsuite/monitor/commons/error/MonitorException.java b/monitor-commons/src/main/java/org/gridsuite/monitor/commons/error/MonitorException.java deleted file mode 100644 index e6359073..00000000 --- a/monitor-commons/src/main/java/org/gridsuite/monitor/commons/error/MonitorException.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (c) 2026, RTE (http://www.rte-france.com) - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - */ -package org.gridsuite.monitor.commons.error; - -import com.powsybl.ws.commons.error.AbstractBusinessException; -import lombok.Getter; -import lombok.NonNull; - -import java.util.Map; - -/** - * @author Franck Lecuyer - */ -@Getter -public class MonitorException extends AbstractBusinessException { - private final MonitorBusinessErrorCode errorCode; - private final transient Map businessErrorValues; - - public MonitorException(MonitorBusinessErrorCode errorCode, String message) { - this(errorCode, message, null, null); - } - - public MonitorException(MonitorBusinessErrorCode errorCode, String message, Throwable cause) { - this(errorCode, message, null, cause); - } - - public MonitorException(MonitorBusinessErrorCode errorCode, String message, Map businessErrorValues) { - this(errorCode, message, businessErrorValues, null); - } - - public MonitorException(MonitorBusinessErrorCode errorCode, String message, Map businessErrorValues, Throwable cause) { - super(message, cause); - this.errorCode = errorCode; - this.businessErrorValues = businessErrorValues != null ? Map.copyOf(businessErrorValues) : Map.of(); - } - - @NonNull - @Override - public MonitorBusinessErrorCode getBusinessErrorCode() { - return errorCode; - } -} diff --git a/monitor-commons/src/main/java/org/gridsuite/monitor/commons/error/MonitorExceptionHandler.java b/monitor-commons/src/main/java/org/gridsuite/monitor/commons/error/MonitorExceptionHandler.java deleted file mode 100644 index 8fc21fd1..00000000 --- a/monitor-commons/src/main/java/org/gridsuite/monitor/commons/error/MonitorExceptionHandler.java +++ /dev/null @@ -1,47 +0,0 @@ -/** - * Copyright (c) 2026, RTE (http://www.rte-france.com) - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - */ -package org.gridsuite.monitor.commons.error; - -import com.powsybl.ws.commons.error.AbstractBusinessExceptionHandler; -import com.powsybl.ws.commons.error.PowsyblWsProblemDetail; -import com.powsybl.ws.commons.error.ServerNameProvider; -import jakarta.servlet.http.HttpServletRequest; -import lombok.NonNull; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.ControllerAdvice; -import org.springframework.web.bind.annotation.ExceptionHandler; - -/** - * @author Franck Lecuyer - */ -@ControllerAdvice -public class MonitorExceptionHandler extends AbstractBusinessExceptionHandler { - - public MonitorExceptionHandler(ServerNameProvider serverNameProvider) { - super(serverNameProvider); - } - - @NonNull - @Override - protected MonitorBusinessErrorCode getBusinessCode(MonitorException ex) { - return ex.getBusinessErrorCode(); - } - - @Override - protected HttpStatus mapStatus(MonitorBusinessErrorCode errorCode) { - return switch (errorCode) { - case DIFFERENT_PROCESS_CONFIG_TYPE -> HttpStatus.BAD_REQUEST; - }; - } - - @ExceptionHandler(MonitorException.class) - protected ResponseEntity handleMonitorServerException( - MonitorException exception, HttpServletRequest request) { - return super.handleDomainException(exception, request); - } -} diff --git a/monitor-commons/src/main/java/org/gridsuite/monitor/commons/types/processconfig/LoadFlowConfig.java b/monitor-commons/src/main/java/org/gridsuite/monitor/commons/types/processconfig/LoadFlowConfig.java index 7f87e751..051b7d31 100644 --- a/monitor-commons/src/main/java/org/gridsuite/monitor/commons/types/processconfig/LoadFlowConfig.java +++ b/monitor-commons/src/main/java/org/gridsuite/monitor/commons/types/processconfig/LoadFlowConfig.java @@ -7,16 +7,12 @@ package org.gridsuite.monitor.commons.types.processconfig; import jakarta.validation.constraints.NotNull; -import org.gridsuite.monitor.commons.error.MonitorException; import org.gridsuite.monitor.commons.types.processexecution.ProcessType; import java.util.List; -import java.util.Map; import java.util.Objects; import java.util.UUID; -import static org.gridsuite.monitor.commons.error.MonitorBusinessErrorCode.DIFFERENT_PROCESS_CONFIG_TYPE; - /** * @author Franck Lecuyer */ @@ -33,10 +29,7 @@ public ProcessType processType() { @Override public List compareWith(ProcessConfig other) { - if (!(other instanceof LoadFlowConfig o)) { - throw new MonitorException(DIFFERENT_PROCESS_CONFIG_TYPE, "Cannot compare different process config types", - Map.of("processConfigEntity1Type", this.processType(), "processConfigEntity2Type", other.processType())); - } + LoadFlowConfig o = (LoadFlowConfig) other; return List.of( new ProcessConfigFieldComparison("modifications", Objects.equals(this.modificationUuids, o.modificationUuids), diff --git a/monitor-commons/src/main/java/org/gridsuite/monitor/commons/types/processconfig/SecurityAnalysisConfig.java b/monitor-commons/src/main/java/org/gridsuite/monitor/commons/types/processconfig/SecurityAnalysisConfig.java index a03dca4a..7e29a823 100644 --- a/monitor-commons/src/main/java/org/gridsuite/monitor/commons/types/processconfig/SecurityAnalysisConfig.java +++ b/monitor-commons/src/main/java/org/gridsuite/monitor/commons/types/processconfig/SecurityAnalysisConfig.java @@ -7,16 +7,12 @@ package org.gridsuite.monitor.commons.types.processconfig; import jakarta.validation.constraints.NotNull; -import org.gridsuite.monitor.commons.error.MonitorException; import org.gridsuite.monitor.commons.types.processexecution.ProcessType; import java.util.List; -import java.util.Map; import java.util.Objects; import java.util.UUID; -import static org.gridsuite.monitor.commons.error.MonitorBusinessErrorCode.DIFFERENT_PROCESS_CONFIG_TYPE; - /** * @author Antoine Bouhours */ @@ -35,10 +31,7 @@ public ProcessType processType() { @Override public List compareWith(ProcessConfig other) { - if (!(other instanceof SecurityAnalysisConfig o)) { - throw new MonitorException(DIFFERENT_PROCESS_CONFIG_TYPE, "Cannot compare different process config types", - Map.of("processConfigEntity1Type", this.processType(), "processConfigEntity2Type", other.processType())); - } + SecurityAnalysisConfig o = (SecurityAnalysisConfig) other; return List.of( new ProcessConfigFieldComparison("modifications", Objects.equals(this.modificationUuids, o.modificationUuids), diff --git a/monitor-commons/src/test/java/org/gridsuite/monitor/commons/error/MonitorBusinessErrorCodeTest.java b/monitor-commons/src/test/java/org/gridsuite/monitor/commons/error/MonitorBusinessErrorCodeTest.java deleted file mode 100644 index e358f915..00000000 --- a/monitor-commons/src/test/java/org/gridsuite/monitor/commons/error/MonitorBusinessErrorCodeTest.java +++ /dev/null @@ -1,23 +0,0 @@ -/** - * Copyright (c) 2026, RTE (http://www.rte-france.com) - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - */ -package org.gridsuite.monitor.commons.error; - -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.EnumSource; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * @author Franck Lecuyer - */ -class MonitorBusinessErrorCodeTest { - @ParameterizedTest - @EnumSource(MonitorBusinessErrorCode.class) - void valueMatchesEnumName(MonitorBusinessErrorCode code) { - assertThat(code.value()).startsWith("monitor."); - } -} diff --git a/monitor-commons/src/test/java/org/gridsuite/monitor/commons/error/MonitorExceptionHandlerTest.java b/monitor-commons/src/test/java/org/gridsuite/monitor/commons/error/MonitorExceptionHandlerTest.java deleted file mode 100644 index 691118d7..00000000 --- a/monitor-commons/src/test/java/org/gridsuite/monitor/commons/error/MonitorExceptionHandlerTest.java +++ /dev/null @@ -1,40 +0,0 @@ -/** - * Copyright (c) 2026, RTE (http://www.rte-france.com) - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - */ -package org.gridsuite.monitor.commons.error; - -import com.powsybl.ws.commons.error.PowsyblWsProblemDetail; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.mock.web.MockHttpServletRequest; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.jupiter.api.Assertions.assertEquals; - -/** - * @author Franck Lecuyer - */ -class MonitorExceptionHandlerTest { - private MonitorExceptionHandler handler; - - @BeforeEach - void setUp() { - handler = new MonitorExceptionHandler(() -> "monitor-server"); - } - - @Test - void mapsBadRequestBusinessErrorToStatus() { - MockHttpServletRequest request = new MockHttpServletRequest("GET", "/results-endpoint/uuid"); - MonitorException exception = new MonitorException(MonitorBusinessErrorCode.DIFFERENT_PROCESS_CONFIG_TYPE, "Cannot compare different process config types"); - ResponseEntity response = handler.handleMonitorServerException(exception, request); - - assertThat(response.getStatusCode()).isEqualTo(HttpStatus.BAD_REQUEST); - assertThat(response.getBody()).isNotNull(); - assertEquals("monitor.differentProcessConfigType", response.getBody().getBusinessErrorCode()); - } -} diff --git a/monitor-commons/src/test/java/org/gridsuite/monitor/commons/types/processconfig/LoadFlowConfigTest.java b/monitor-commons/src/test/java/org/gridsuite/monitor/commons/types/processconfig/LoadFlowConfigTest.java index d33803e3..bf77914a 100644 --- a/monitor-commons/src/test/java/org/gridsuite/monitor/commons/types/processconfig/LoadFlowConfigTest.java +++ b/monitor-commons/src/test/java/org/gridsuite/monitor/commons/types/processconfig/LoadFlowConfigTest.java @@ -6,8 +6,6 @@ */ package org.gridsuite.monitor.commons.types.processconfig; -import org.gridsuite.monitor.commons.error.MonitorException; -import org.gridsuite.monitor.commons.types.processexecution.ProcessType; import org.junit.jupiter.api.Test; import java.util.List; @@ -15,7 +13,6 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.gridsuite.monitor.commons.error.MonitorBusinessErrorCode.DIFFERENT_PROCESS_CONFIG_TYPE; /** * @author Caroline Jeandat {@literal } @@ -103,14 +100,6 @@ void compareWithShouldThrowWhenProcessTypesAreDifferent() { LoadFlowConfig loadFlowConfig = new LoadFlowConfig(UUID.randomUUID(), List.of(UUID.randomUUID())); SecurityAnalysisConfig securityAnalysisConfig = new SecurityAnalysisConfig(UUID.randomUUID(), List.of(UUID.randomUUID()), UUID.randomUUID()); - assertThatThrownBy(() -> loadFlowConfig.compareWith(securityAnalysisConfig)) - .isInstanceOf(MonitorException.class) - .satisfies(ex -> { - MonitorException e = (MonitorException) ex; - assertThat(e.getErrorCode()).isEqualTo(DIFFERENT_PROCESS_CONFIG_TYPE); - assertThat(e.getBusinessErrorValues()) - .containsEntry("processConfigEntity1Type", ProcessType.LOADFLOW) - .containsEntry("processConfigEntity2Type", ProcessType.SECURITY_ANALYSIS); - }); + assertThatThrownBy(() -> loadFlowConfig.compareWith(securityAnalysisConfig)).isInstanceOf(ClassCastException.class); } } diff --git a/monitor-commons/src/test/java/org/gridsuite/monitor/commons/types/processconfig/SecurityAnalysisConfigTest.java b/monitor-commons/src/test/java/org/gridsuite/monitor/commons/types/processconfig/SecurityAnalysisConfigTest.java index 8b52acbe..8513da39 100644 --- a/monitor-commons/src/test/java/org/gridsuite/monitor/commons/types/processconfig/SecurityAnalysisConfigTest.java +++ b/monitor-commons/src/test/java/org/gridsuite/monitor/commons/types/processconfig/SecurityAnalysisConfigTest.java @@ -6,8 +6,6 @@ */ package org.gridsuite.monitor.commons.types.processconfig; -import org.gridsuite.monitor.commons.error.MonitorException; -import org.gridsuite.monitor.commons.types.processexecution.ProcessType; import org.junit.jupiter.api.Test; import java.util.List; @@ -15,7 +13,6 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.gridsuite.monitor.commons.error.MonitorBusinessErrorCode.DIFFERENT_PROCESS_CONFIG_TYPE; /** * @author Caroline Jeandat {@literal } @@ -128,14 +125,6 @@ void compareWithShouldThrowWhenProcessTypesAreDifferent() { SecurityAnalysisConfig securityAnalysisConfig = new SecurityAnalysisConfig(UUID.randomUUID(), List.of(UUID.randomUUID()), UUID.randomUUID()); LoadFlowConfig loadFlowConfig = new LoadFlowConfig(UUID.randomUUID(), List.of(UUID.randomUUID())); - assertThatThrownBy(() -> securityAnalysisConfig.compareWith(loadFlowConfig)) - .isInstanceOf(MonitorException.class) - .satisfies(ex -> { - MonitorException e = (MonitorException) ex; - assertThat(e.getErrorCode()).isEqualTo(DIFFERENT_PROCESS_CONFIG_TYPE); - assertThat(e.getBusinessErrorValues()) - .containsEntry("processConfigEntity1Type", ProcessType.SECURITY_ANALYSIS) - .containsEntry("processConfigEntity2Type", ProcessType.LOADFLOW); - }); + assertThatThrownBy(() -> securityAnalysisConfig.compareWith(loadFlowConfig)).isInstanceOf(ClassCastException.class); } } diff --git a/monitor-server/src/main/java/org/gridsuite/monitor/server/controllers/ProcessConfigController.java b/monitor-server/src/main/java/org/gridsuite/monitor/server/controllers/ProcessConfigController.java index e54f660a..52a3e020 100644 --- a/monitor-server/src/main/java/org/gridsuite/monitor/server/controllers/ProcessConfigController.java +++ b/monitor-server/src/main/java/org/gridsuite/monitor/server/controllers/ProcessConfigController.java @@ -134,7 +134,11 @@ public ResponseEntity compareProcessConfigs( @Parameter(description = "First process config UUID") @RequestParam("uuid1") UUID uuid1, @Parameter(description = "Second process config UUID") @RequestParam("uuid2") UUID uuid2) { - Optional comparison = processConfigService.compareProcessConfigs(uuid1, uuid2); - return comparison.map(c -> ResponseEntity.status(HttpStatus.OK).body(c)).orElseGet(() -> ResponseEntity.status(HttpStatus.NOT_FOUND).build()); + try { + Optional comparison = processConfigService.compareProcessConfigs(uuid1, uuid2); + return comparison.map(c -> ResponseEntity.status(HttpStatus.OK).body(c)).orElseGet(() -> ResponseEntity.status(HttpStatus.NOT_FOUND).build()); + } catch (ClassCastException e) { + return ResponseEntity.status(HttpStatus.BAD_REQUEST).build(); + } } } diff --git a/monitor-server/src/test/java/org/gridsuite/monitor/server/controllers/ProcessConfigControllerTest.java b/monitor-server/src/test/java/org/gridsuite/monitor/server/controllers/ProcessConfigControllerTest.java index b8e5baca..1dd45b42 100644 --- a/monitor-server/src/test/java/org/gridsuite/monitor/server/controllers/ProcessConfigControllerTest.java +++ b/monitor-server/src/test/java/org/gridsuite/monitor/server/controllers/ProcessConfigControllerTest.java @@ -7,7 +7,6 @@ package org.gridsuite.monitor.server.controllers; import com.fasterxml.jackson.databind.ObjectMapper; -import org.gridsuite.monitor.commons.error.MonitorExceptionHandler; import org.gridsuite.monitor.server.PropertyServerNameProvider; import org.gridsuite.monitor.server.dto.processconfig.MetadataInfos; import org.gridsuite.monitor.server.dto.processconfig.PersistedProcessConfig; @@ -16,12 +15,10 @@ import org.gridsuite.monitor.commons.types.processexecution.ProcessType; import org.gridsuite.monitor.server.dto.processconfig.ProcessConfigComparison; import org.gridsuite.monitor.commons.types.processconfig.ProcessConfigFieldComparison; -import org.gridsuite.monitor.commons.error.MonitorException; import org.gridsuite.monitor.server.services.processconfig.ProcessConfigService; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; -import org.springframework.context.annotation.Import; import org.springframework.http.MediaType; import org.springframework.test.context.bean.override.mockito.MockitoBean; import org.springframework.test.web.servlet.MockMvc; @@ -30,7 +27,6 @@ import java.util.Optional; import java.util.UUID; -import static org.gridsuite.monitor.commons.error.MonitorBusinessErrorCode.DIFFERENT_PROCESS_CONFIG_TYPE; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -46,7 +42,6 @@ * @author Franck Lecuyer */ @WebMvcTest(controllers = { ProcessConfigController.class, PropertyServerNameProvider.class }) -@Import(MonitorExceptionHandler.class) class ProcessConfigControllerTest { @Autowired @@ -346,7 +341,7 @@ void compareProcessConfigsShouldReturn400WhenDifferentTypes() throws Exception { UUID uuid2 = UUID.randomUUID(); when(processConfigService.compareProcessConfigs(any(), any())) - .thenThrow(new MonitorException(DIFFERENT_PROCESS_CONFIG_TYPE, "Cannot compare different process config types")); + .thenThrow(new ClassCastException()); mockMvc.perform(get("/v1/process-configs/compare") .param("uuid1", uuid1.toString()) diff --git a/monitor-server/src/test/java/org/gridsuite/monitor/server/services/processconfig/ProcessConfigServiceTest.java b/monitor-server/src/test/java/org/gridsuite/monitor/server/services/processconfig/ProcessConfigServiceTest.java index c7807e86..40a0137e 100644 --- a/monitor-server/src/test/java/org/gridsuite/monitor/server/services/processconfig/ProcessConfigServiceTest.java +++ b/monitor-server/src/test/java/org/gridsuite/monitor/server/services/processconfig/ProcessConfigServiceTest.java @@ -17,7 +17,6 @@ import org.gridsuite.monitor.server.entities.processconfig.LoadFlowConfigEntity; import org.gridsuite.monitor.server.entities.processconfig.ProcessConfigEntity; import org.gridsuite.monitor.server.entities.processconfig.SecurityAnalysisConfigEntity; -import org.gridsuite.monitor.commons.error.MonitorException; import org.gridsuite.monitor.server.repositories.ProcessConfigRepository; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -29,7 +28,6 @@ import java.util.*; import static org.assertj.core.api.Assertions.*; -import static org.gridsuite.monitor.commons.error.MonitorBusinessErrorCode.DIFFERENT_PROCESS_CONFIG_TYPE; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.*; @@ -368,14 +366,10 @@ void compareProcessConfigsShouldThrowWhenProcessTypesAreDifferent() { when(processConfigEntity2.getProcessType()).thenReturn(ProcessType.LOADFLOW); when(handler2.toProcessConfig(processConfigEntity2)).thenReturn(processConfig2); when(processConfig1.compareWith(processConfig2)) - .thenThrow(new MonitorException(DIFFERENT_PROCESS_CONFIG_TYPE, "Cannot compare different process config types")); + .thenThrow(new ClassCastException()); assertThatThrownBy(() -> processConfigService.compareProcessConfigs(processConfigUuid1, processConfigUuid2)) - .isInstanceOf(MonitorException.class) - .satisfies(ex -> { - MonitorException e = (MonitorException) ex; - assertThat(e.getErrorCode()).isEqualTo(DIFFERENT_PROCESS_CONFIG_TYPE); - }); + .isInstanceOf(ClassCastException.class); verify(processConfigRepository).findById(processConfigUuid1); verify(processConfigRepository).findById(processConfigUuid2); verify(handler).toProcessConfig(processConfigEntity1); From e572b18ccd4d9a6c1506651ce95bf995bf87ff63 Mon Sep 17 00:00:00 2001 From: Caroline Jeandat Date: Thu, 25 Jun 2026 17:20:14 +0200 Subject: [PATCH 6/9] remove spring test dependency in monitor-commons Signed-off-by: Caroline Jeandat --- monitor-commons/pom.xml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/monitor-commons/pom.xml b/monitor-commons/pom.xml index ade2437d..89263854 100644 --- a/monitor-commons/pom.xml +++ b/monitor-commons/pom.xml @@ -43,10 +43,5 @@ assertj-core test - - org.springframework - spring-test - test - From 61d17d8ca3f3fb6bec2ed769f42e2019967d0677 Mon Sep 17 00:00:00 2001 From: carojeandat <112859659+carojeandat@users.noreply.github.com> Date: Thu, 25 Jun 2026 17:44:41 +0200 Subject: [PATCH 7/9] fix business error test name Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- .../monitor/server/error/MonitorServerExceptionHandlerTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/monitor-server/src/test/java/org/gridsuite/monitor/server/error/MonitorServerExceptionHandlerTest.java b/monitor-server/src/test/java/org/gridsuite/monitor/server/error/MonitorServerExceptionHandlerTest.java index fe911d4a..a5a176f6 100644 --- a/monitor-server/src/test/java/org/gridsuite/monitor/server/error/MonitorServerExceptionHandlerTest.java +++ b/monitor-server/src/test/java/org/gridsuite/monitor/server/error/MonitorServerExceptionHandlerTest.java @@ -28,7 +28,7 @@ void setUp() { } @Test - void mapsBadRequestBusinessErrorToStatus() { + void mapsNotFoundBusinessErrorToStatus() { MockHttpServletRequest request = new MockHttpServletRequest("GET", "/results-endpoint/uuid"); MonitorServerException exception = new MonitorServerException(MonitorServerBusinessErrorCode.PROCESS_CONFIG_NOT_FOUND, "Process config not found"); ResponseEntity response = handler.handleMonitorServerException(exception, request); From 715a1d5b01a25b38b5e628f85cb459714c916786 Mon Sep 17 00:00:00 2001 From: Caroline Jeandat Date: Fri, 26 Jun 2026 13:16:16 +0200 Subject: [PATCH 8/9] rename toProcessConfig to toDto Signed-off-by: Caroline Jeandat --- .../AbstractProcessConfigHandler.java | 4 +-- .../processconfig/ProcessConfigHandler.java | 2 +- .../processconfig/ProcessConfigService.java | 11 +++--- .../AbstractProcessConfigHandlerTest.java | 4 +-- .../LoadFlowConfigHandlerTest.java | 17 +++++----- .../ProcessConfigServiceTest.java | 34 +++++++++---------- .../SecurityAnalysisConfigHandlerTest.java | 17 +++++----- 7 files changed, 47 insertions(+), 42 deletions(-) diff --git a/monitor-server/src/main/java/org/gridsuite/monitor/server/services/processconfig/AbstractProcessConfigHandler.java b/monitor-server/src/main/java/org/gridsuite/monitor/server/services/processconfig/AbstractProcessConfigHandler.java index 7fa5f7d8..e35824dd 100644 --- a/monitor-server/src/main/java/org/gridsuite/monitor/server/services/processconfig/AbstractProcessConfigHandler.java +++ b/monitor-server/src/main/java/org/gridsuite/monitor/server/services/processconfig/AbstractProcessConfigHandler.java @@ -29,7 +29,7 @@ public void update(C processConfig, E entity) { @Override public E copyEntity(E sourceEntity) { - return toEntity(toProcessConfig(sourceEntity)); + return toEntity(toDto(sourceEntity)); } @Override @@ -38,7 +38,7 @@ public E toEntity(C processConfig) { } @Override - public C toProcessConfig(E entity) { + public C toDto(E entity) { return mapper.toDto(entity); } } diff --git a/monitor-server/src/main/java/org/gridsuite/monitor/server/services/processconfig/ProcessConfigHandler.java b/monitor-server/src/main/java/org/gridsuite/monitor/server/services/processconfig/ProcessConfigHandler.java index 458a2563..f80bfd6e 100644 --- a/monitor-server/src/main/java/org/gridsuite/monitor/server/services/processconfig/ProcessConfigHandler.java +++ b/monitor-server/src/main/java/org/gridsuite/monitor/server/services/processconfig/ProcessConfigHandler.java @@ -23,5 +23,5 @@ public interface ProcessConfigHandler deleteProcessConfig(UUID processConfigUuid) { } private PersistedProcessConfig toPersistedProcessConfig(ProcessConfigEntity entity) { - ProcessConfig processConfig = getHandler(entity.getProcessType()).toProcessConfig(entity); - return new PersistedProcessConfig(entity.getId(), processConfig); + return new PersistedProcessConfig(entity.getId(), toProcessConfig(entity)); + } + + private ProcessConfig toProcessConfig(ProcessConfigEntity entity) { + return getHandler(entity.getProcessType()).toDto(entity); } @Transactional(readOnly = true) @@ -119,8 +122,8 @@ public Optional compareProcessConfigs(UUID uuid1, UUID return Optional.empty(); } - ProcessConfig processConfig1 = getHandler(processConfigEntity1.get().getProcessType()).toProcessConfig(processConfigEntity1.get()); - ProcessConfig processConfig2 = getHandler(processConfigEntity2.get().getProcessType()).toProcessConfig(processConfigEntity2.get()); + ProcessConfig processConfig1 = toProcessConfig(processConfigEntity1.get()); + ProcessConfig processConfig2 = toProcessConfig(processConfigEntity2.get()); List differences = processConfig1.compareWith(processConfig2); boolean identical = differences.stream().allMatch(ProcessConfigFieldComparison::identical); diff --git a/monitor-server/src/test/java/org/gridsuite/monitor/server/services/processconfig/AbstractProcessConfigHandlerTest.java b/monitor-server/src/test/java/org/gridsuite/monitor/server/services/processconfig/AbstractProcessConfigHandlerTest.java index ef87fcbd..c607cf22 100644 --- a/monitor-server/src/test/java/org/gridsuite/monitor/server/services/processconfig/AbstractProcessConfigHandlerTest.java +++ b/monitor-server/src/test/java/org/gridsuite/monitor/server/services/processconfig/AbstractProcessConfigHandlerTest.java @@ -84,13 +84,13 @@ void toEntityTest() { } @Test - void toProcessConfigTest() { + void toDtoTest() { E processConfigEntity = createProcessConfigEntity(); C expectedProcessConfig = createProcessConfig(); when(mapper.toDto(processConfigEntity)).thenReturn(expectedProcessConfig); - ProcessConfig result = handler.toProcessConfig(processConfigEntity); + ProcessConfig result = handler.toDto(processConfigEntity); assertThat(result).isEqualTo(expectedProcessConfig); verify(mapper).toDto(processConfigEntity); diff --git a/monitor-server/src/test/java/org/gridsuite/monitor/server/services/processconfig/LoadFlowConfigHandlerTest.java b/monitor-server/src/test/java/org/gridsuite/monitor/server/services/processconfig/LoadFlowConfigHandlerTest.java index d2f8695f..a7c62d22 100644 --- a/monitor-server/src/test/java/org/gridsuite/monitor/server/services/processconfig/LoadFlowConfigHandlerTest.java +++ b/monitor-server/src/test/java/org/gridsuite/monitor/server/services/processconfig/LoadFlowConfigHandlerTest.java @@ -25,6 +25,15 @@ */ @ExtendWith(MockitoExtension.class) class LoadFlowConfigHandlerTest extends AbstractProcessConfigHandlerTest { + + @Override + @BeforeEach + protected void setUp() { + LoadFlowConfigMapper realMapper = Mappers.getMapper(LoadFlowConfigMapper.class); + mapper = Mockito.spy(realMapper); + handler = new LoadFlowConfigHandler(mapper); + } + @Override ProcessType getProcessType() { return ProcessType.LOADFLOW; @@ -39,12 +48,4 @@ LoadFlowConfig createProcessConfig() { LoadFlowConfigEntity createProcessConfigEntity() { return new LoadFlowConfigEntity(); } - - @Override - @BeforeEach - protected void setUp() { - LoadFlowConfigMapper realMapper = Mappers.getMapper(LoadFlowConfigMapper.class); - mapper = Mockito.spy(realMapper); - handler = new LoadFlowConfigHandler(mapper); - } } diff --git a/monitor-server/src/test/java/org/gridsuite/monitor/server/services/processconfig/ProcessConfigServiceTest.java b/monitor-server/src/test/java/org/gridsuite/monitor/server/services/processconfig/ProcessConfigServiceTest.java index 40a0137e..4443ef7a 100644 --- a/monitor-server/src/test/java/org/gridsuite/monitor/server/services/processconfig/ProcessConfigServiceTest.java +++ b/monitor-server/src/test/java/org/gridsuite/monitor/server/services/processconfig/ProcessConfigServiceTest.java @@ -84,7 +84,7 @@ void getProcessConfig() { when(processConfigRepository.findById(processConfigUuid)).thenReturn(Optional.of(processConfigEntity)); when(processConfigEntity.getProcessType()).thenReturn(PROCESS_TYPE); - when(handler.toProcessConfig(processConfigEntity)).thenReturn(processConfig); + when(handler.toDto(processConfigEntity)).thenReturn(processConfig); when(processConfigEntity.getId()).thenReturn(processConfigUuid); Optional result = processConfigService.getProcessConfig(processConfigUuid); @@ -92,7 +92,7 @@ void getProcessConfig() { assertThat(result).isPresent(); assertThat(result.get().processConfig()).isEqualTo(processConfig); verify(processConfigRepository).findById(processConfigUuid); - verify(handler).toProcessConfig(processConfigEntity); + verify(handler).toDto(processConfigEntity); } @Test @@ -105,7 +105,7 @@ void getProcessConfigNotFound() { assertThat(result).isEmpty(); verify(processConfigRepository).findById(processConfigUuid); - verify(handler, never()).toProcessConfig(any()); + verify(handler, never()).toDto(any()); } @Test @@ -114,7 +114,7 @@ void getProcessConfigs() { when(processConfigRepository.findAllByProcessType(PROCESS_TYPE)).thenReturn(List.of(processConfigEntity)); when(processConfigEntity.getProcessType()).thenReturn(PROCESS_TYPE); - when(handler.toProcessConfig(processConfigEntity)).thenReturn(processConfig); + when(handler.toDto(processConfigEntity)).thenReturn(processConfig); when(processConfigEntity.getId()).thenReturn(processConfigUuid); List result = processConfigService.getProcessConfigs(PROCESS_TYPE); @@ -122,7 +122,7 @@ void getProcessConfigs() { assertThat(result).hasSize(1); assertThat(result.getFirst().processConfig()).isEqualTo(processConfig); verify(processConfigRepository).findAllByProcessType(PROCESS_TYPE); - verify(handler).toProcessConfig(processConfigEntity); + verify(handler).toDto(processConfigEntity); } @Test @@ -264,7 +264,7 @@ void compareProcessConfigsWithEqualProcessConfigs() { when(processConfigRepository.findById(processConfigUuid1)).thenReturn(Optional.of(processConfigEntity)); when(processConfigRepository.findById(processConfigUuid2)).thenReturn(Optional.of(processConfigEntity)); when(processConfigEntity.getProcessType()).thenReturn(PROCESS_TYPE); - when(handler.toProcessConfig(processConfigEntity)).thenReturn(processConfig); + when(handler.toDto(processConfigEntity)).thenReturn(processConfig); when(processConfig.compareWith(processConfig)).thenReturn(List.of(fieldComparison)); Optional result = processConfigService.compareProcessConfigs(processConfigUuid1, processConfigUuid2); @@ -274,7 +274,7 @@ void compareProcessConfigsWithEqualProcessConfigs() { .contains(new ProcessConfigComparison(processConfigUuid1, processConfigUuid2, true, List.of(fieldComparison))); verify(processConfigRepository).findById(processConfigUuid1); verify(processConfigRepository).findById(processConfigUuid2); - verify(handler, times(2)).toProcessConfig(processConfigEntity); + verify(handler, times(2)).toDto(processConfigEntity); verify(processConfig).compareWith(processConfig); } @@ -292,8 +292,8 @@ void compareProcessConfigsWithDifferentProcessConfigs() { when(processConfigRepository.findById(processConfigUuid2)).thenReturn(Optional.of(processConfigEntity2)); when(processConfigEntity1.getProcessType()).thenReturn(PROCESS_TYPE); when(processConfigEntity2.getProcessType()).thenReturn(PROCESS_TYPE); - when(handler.toProcessConfig(processConfigEntity1)).thenReturn(processConfig1); - when(handler.toProcessConfig(processConfigEntity2)).thenReturn(processConfig2); + when(handler.toDto(processConfigEntity1)).thenReturn(processConfig1); + when(handler.toDto(processConfigEntity2)).thenReturn(processConfig2); when(processConfig1.compareWith(processConfig2)).thenReturn(List.of(fieldComparison)); Optional result = processConfigService.compareProcessConfigs(processConfigUuid1, processConfigUuid2); @@ -303,8 +303,8 @@ void compareProcessConfigsWithDifferentProcessConfigs() { .contains(new ProcessConfigComparison(processConfigUuid1, processConfigUuid2, false, List.of(fieldComparison))); verify(processConfigRepository).findById(processConfigUuid1); verify(processConfigRepository).findById(processConfigUuid2); - verify(handler).toProcessConfig(processConfigEntity1); - verify(handler).toProcessConfig(processConfigEntity2); + verify(handler).toDto(processConfigEntity1); + verify(handler).toDto(processConfigEntity2); verify(processConfig1).compareWith(processConfig2); } @@ -320,7 +320,7 @@ void compareProcessConfigWithFirstProcessConfigNotFound() { assertThat(result).isEmpty(); verify(processConfigRepository).findById(processConfigUuid1); - verify(handler, never()).toProcessConfig(any()); + verify(handler, never()).toDto(any()); } @Test @@ -339,7 +339,7 @@ void compareProcessConfigWithSecondProcessConfigNotFound() { assertThat(result).isEmpty(); verify(processConfigRepository).findById(processConfigUuid1); verify(processConfigRepository).findById(processConfigUuid2); - verify(handler, never()).toProcessConfig(any()); + verify(handler, never()).toDto(any()); } @Test @@ -362,9 +362,9 @@ void compareProcessConfigsShouldThrowWhenProcessTypesAreDifferent() { when(processConfigRepository.findById(processConfigUuid1)).thenReturn(Optional.of(processConfigEntity1)); when(processConfigRepository.findById(processConfigUuid2)).thenReturn(Optional.of(processConfigEntity2)); when(processConfigEntity1.getProcessType()).thenReturn(ProcessType.SECURITY_ANALYSIS); - when(handler.toProcessConfig(processConfigEntity1)).thenReturn(processConfig1); + when(handler.toDto(processConfigEntity1)).thenReturn(processConfig1); when(processConfigEntity2.getProcessType()).thenReturn(ProcessType.LOADFLOW); - when(handler2.toProcessConfig(processConfigEntity2)).thenReturn(processConfig2); + when(handler2.toDto(processConfigEntity2)).thenReturn(processConfig2); when(processConfig1.compareWith(processConfig2)) .thenThrow(new ClassCastException()); @@ -372,8 +372,8 @@ void compareProcessConfigsShouldThrowWhenProcessTypesAreDifferent() { .isInstanceOf(ClassCastException.class); verify(processConfigRepository).findById(processConfigUuid1); verify(processConfigRepository).findById(processConfigUuid2); - verify(handler).toProcessConfig(processConfigEntity1); - verify(handler2).toProcessConfig(processConfigEntity2); + verify(handler).toDto(processConfigEntity1); + verify(handler2).toDto(processConfigEntity2); verify(processConfig1).compareWith(processConfig2); } } diff --git a/monitor-server/src/test/java/org/gridsuite/monitor/server/services/processconfig/SecurityAnalysisConfigHandlerTest.java b/monitor-server/src/test/java/org/gridsuite/monitor/server/services/processconfig/SecurityAnalysisConfigHandlerTest.java index 08de5f42..5aeeeb7a 100644 --- a/monitor-server/src/test/java/org/gridsuite/monitor/server/services/processconfig/SecurityAnalysisConfigHandlerTest.java +++ b/monitor-server/src/test/java/org/gridsuite/monitor/server/services/processconfig/SecurityAnalysisConfigHandlerTest.java @@ -24,6 +24,15 @@ */ @ExtendWith(MockitoExtension.class) class SecurityAnalysisConfigHandlerTest extends AbstractProcessConfigHandlerTest { + + @Override + @BeforeEach + protected void setUp() { + SecurityAnalysisConfigMapper realMapper = Mappers.getMapper(SecurityAnalysisConfigMapper.class); + mapper = Mockito.spy(realMapper); + handler = new SecurityAnalysisConfigHandler(mapper); + } + @Override ProcessType getProcessType() { return ProcessType.SECURITY_ANALYSIS; @@ -38,12 +47,4 @@ SecurityAnalysisConfig createProcessConfig() { SecurityAnalysisConfigEntity createProcessConfigEntity() { return new SecurityAnalysisConfigEntity(); } - - @Override - @BeforeEach - protected void setUp() { - SecurityAnalysisConfigMapper realMapper = Mappers.getMapper(SecurityAnalysisConfigMapper.class); - mapper = Mockito.spy(realMapper); - handler = new SecurityAnalysisConfigHandler(mapper); - } } From 7673e6da253fdd12b4a918093f7b0a050175a42b Mon Sep 17 00:00:00 2001 From: Caroline Jeandat Date: Fri, 26 Jun 2026 13:44:06 +0200 Subject: [PATCH 9/9] add business error for process type mismatch Signed-off-by: Caroline Jeandat --- .../error/MonitorServerBusinessErrorCode.java | 2 +- .../error/MonitorServerExceptionHandler.java | 2 +- .../processconfig/ProcessConfigService.java | 8 ++++++ .../ProcessConfigControllerTest.java | 4 ++- .../MonitorServerExceptionHandlerTest.java | 9 +++--- .../ProcessConfigServiceTest.java | 28 ++++++------------- 6 files changed, 26 insertions(+), 27 deletions(-) diff --git a/monitor-server/src/main/java/org/gridsuite/monitor/server/error/MonitorServerBusinessErrorCode.java b/monitor-server/src/main/java/org/gridsuite/monitor/server/error/MonitorServerBusinessErrorCode.java index a60a058b..db96aa3a 100644 --- a/monitor-server/src/main/java/org/gridsuite/monitor/server/error/MonitorServerBusinessErrorCode.java +++ b/monitor-server/src/main/java/org/gridsuite/monitor/server/error/MonitorServerBusinessErrorCode.java @@ -12,7 +12,7 @@ * @author Franck Lecuyer */ public enum MonitorServerBusinessErrorCode implements BusinessErrorCode { - PROCESS_CONFIG_NOT_FOUND("monitor.server.processConfigNotFound"); + DIFFERENT_PROCESS_CONFIG_TYPE("monitor.server.differentProcessConfigType"); private final String code; diff --git a/monitor-server/src/main/java/org/gridsuite/monitor/server/error/MonitorServerExceptionHandler.java b/monitor-server/src/main/java/org/gridsuite/monitor/server/error/MonitorServerExceptionHandler.java index 83e97989..05aa2258 100644 --- a/monitor-server/src/main/java/org/gridsuite/monitor/server/error/MonitorServerExceptionHandler.java +++ b/monitor-server/src/main/java/org/gridsuite/monitor/server/error/MonitorServerExceptionHandler.java @@ -35,7 +35,7 @@ protected MonitorServerBusinessErrorCode getBusinessCode(MonitorServerException @Override protected HttpStatus mapStatus(MonitorServerBusinessErrorCode errorCode) { return switch (errorCode) { - case PROCESS_CONFIG_NOT_FOUND -> HttpStatus.NOT_FOUND; + case DIFFERENT_PROCESS_CONFIG_TYPE -> HttpStatus.BAD_REQUEST; }; } diff --git a/monitor-server/src/main/java/org/gridsuite/monitor/server/services/processconfig/ProcessConfigService.java b/monitor-server/src/main/java/org/gridsuite/monitor/server/services/processconfig/ProcessConfigService.java index 944179c4..fe8bdafc 100644 --- a/monitor-server/src/main/java/org/gridsuite/monitor/server/services/processconfig/ProcessConfigService.java +++ b/monitor-server/src/main/java/org/gridsuite/monitor/server/services/processconfig/ProcessConfigService.java @@ -13,6 +13,7 @@ import org.gridsuite.monitor.commons.types.processconfig.ProcessConfigFieldComparison; import org.gridsuite.monitor.server.dto.processconfig.PersistedProcessConfig; import org.gridsuite.monitor.server.entities.processconfig.ProcessConfigEntity; +import org.gridsuite.monitor.server.error.MonitorServerException; import org.gridsuite.monitor.server.repositories.ProcessConfigRepository; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -21,6 +22,8 @@ import java.util.function.Function; import java.util.stream.Collectors; +import static org.gridsuite.monitor.server.error.MonitorServerBusinessErrorCode.DIFFERENT_PROCESS_CONFIG_TYPE; + /** * @author Franck Lecuyer */ @@ -122,6 +125,11 @@ public Optional compareProcessConfigs(UUID uuid1, UUID return Optional.empty(); } + if (processConfigEntity1.get().getProcessType() != processConfigEntity2.get().getProcessType()) { + throw new MonitorServerException(DIFFERENT_PROCESS_CONFIG_TYPE, "Cannot compare different process config types", + Map.of("processConfigEntity1Type", processConfigEntity1.get().getProcessType(), "processConfigEntity2Type", processConfigEntity2.get().getProcessType())); + } + ProcessConfig processConfig1 = toProcessConfig(processConfigEntity1.get()); ProcessConfig processConfig2 = toProcessConfig(processConfigEntity2.get()); diff --git a/monitor-server/src/test/java/org/gridsuite/monitor/server/controllers/ProcessConfigControllerTest.java b/monitor-server/src/test/java/org/gridsuite/monitor/server/controllers/ProcessConfigControllerTest.java index 1dd45b42..164d62e6 100644 --- a/monitor-server/src/test/java/org/gridsuite/monitor/server/controllers/ProcessConfigControllerTest.java +++ b/monitor-server/src/test/java/org/gridsuite/monitor/server/controllers/ProcessConfigControllerTest.java @@ -15,6 +15,7 @@ import org.gridsuite.monitor.commons.types.processexecution.ProcessType; import org.gridsuite.monitor.server.dto.processconfig.ProcessConfigComparison; import org.gridsuite.monitor.commons.types.processconfig.ProcessConfigFieldComparison; +import org.gridsuite.monitor.server.error.MonitorServerException; import org.gridsuite.monitor.server.services.processconfig.ProcessConfigService; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; @@ -27,6 +28,7 @@ import java.util.Optional; import java.util.UUID; +import static org.gridsuite.monitor.server.error.MonitorServerBusinessErrorCode.DIFFERENT_PROCESS_CONFIG_TYPE; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -341,7 +343,7 @@ void compareProcessConfigsShouldReturn400WhenDifferentTypes() throws Exception { UUID uuid2 = UUID.randomUUID(); when(processConfigService.compareProcessConfigs(any(), any())) - .thenThrow(new ClassCastException()); + .thenThrow(new MonitorServerException(DIFFERENT_PROCESS_CONFIG_TYPE, "Cannot compare different process config types")); mockMvc.perform(get("/v1/process-configs/compare") .param("uuid1", uuid1.toString()) diff --git a/monitor-server/src/test/java/org/gridsuite/monitor/server/error/MonitorServerExceptionHandlerTest.java b/monitor-server/src/test/java/org/gridsuite/monitor/server/error/MonitorServerExceptionHandlerTest.java index a5a176f6..d507307c 100644 --- a/monitor-server/src/test/java/org/gridsuite/monitor/server/error/MonitorServerExceptionHandlerTest.java +++ b/monitor-server/src/test/java/org/gridsuite/monitor/server/error/MonitorServerExceptionHandlerTest.java @@ -14,6 +14,7 @@ import org.springframework.mock.web.MockHttpServletRequest; import static org.assertj.core.api.Assertions.assertThat; +import static org.gridsuite.monitor.server.error.MonitorServerBusinessErrorCode.DIFFERENT_PROCESS_CONFIG_TYPE; import static org.junit.jupiter.api.Assertions.assertEquals; /** @@ -28,13 +29,13 @@ void setUp() { } @Test - void mapsNotFoundBusinessErrorToStatus() { + void mapsBadRequestBusinessErrorToStatus() { MockHttpServletRequest request = new MockHttpServletRequest("GET", "/results-endpoint/uuid"); - MonitorServerException exception = new MonitorServerException(MonitorServerBusinessErrorCode.PROCESS_CONFIG_NOT_FOUND, "Process config not found"); + MonitorServerException exception = new MonitorServerException(DIFFERENT_PROCESS_CONFIG_TYPE, "Cannot compare different process config types"); ResponseEntity response = handler.handleMonitorServerException(exception, request); - assertThat(response.getStatusCode()).isEqualTo(HttpStatus.NOT_FOUND); + assertThat(response.getStatusCode()).isEqualTo(HttpStatus.BAD_REQUEST); assertThat(response.getBody()).isNotNull(); - assertEquals("monitor.server.processConfigNotFound", response.getBody().getBusinessErrorCode()); + assertEquals("monitor.server.differentProcessConfigType", response.getBody().getBusinessErrorCode()); } } diff --git a/monitor-server/src/test/java/org/gridsuite/monitor/server/services/processconfig/ProcessConfigServiceTest.java b/monitor-server/src/test/java/org/gridsuite/monitor/server/services/processconfig/ProcessConfigServiceTest.java index 4443ef7a..9ddf1bb7 100644 --- a/monitor-server/src/test/java/org/gridsuite/monitor/server/services/processconfig/ProcessConfigServiceTest.java +++ b/monitor-server/src/test/java/org/gridsuite/monitor/server/services/processconfig/ProcessConfigServiceTest.java @@ -6,9 +6,7 @@ */ package org.gridsuite.monitor.server.services.processconfig; -import org.gridsuite.monitor.commons.types.processconfig.LoadFlowConfig; import org.gridsuite.monitor.commons.types.processconfig.ProcessConfig; -import org.gridsuite.monitor.commons.types.processconfig.SecurityAnalysisConfig; import org.gridsuite.monitor.commons.types.processexecution.ProcessType; import org.gridsuite.monitor.server.dto.processconfig.MetadataInfos; import org.gridsuite.monitor.server.dto.processconfig.PersistedProcessConfig; @@ -17,6 +15,7 @@ import org.gridsuite.monitor.server.entities.processconfig.LoadFlowConfigEntity; import org.gridsuite.monitor.server.entities.processconfig.ProcessConfigEntity; import org.gridsuite.monitor.server.entities.processconfig.SecurityAnalysisConfigEntity; +import org.gridsuite.monitor.server.error.MonitorServerException; import org.gridsuite.monitor.server.repositories.ProcessConfigRepository; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -28,6 +27,7 @@ import java.util.*; import static org.assertj.core.api.Assertions.*; +import static org.gridsuite.monitor.server.error.MonitorServerBusinessErrorCode.DIFFERENT_PROCESS_CONFIG_TYPE; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.*; @@ -348,32 +348,20 @@ void compareProcessConfigsShouldThrowWhenProcessTypesAreDifferent() { UUID processConfigUuid2 = UUID.randomUUID(); ProcessConfigEntity processConfigEntity1 = Mockito.mock(SecurityAnalysisConfigEntity.class); ProcessConfigEntity processConfigEntity2 = Mockito.mock(LoadFlowConfigEntity.class); - ProcessConfig processConfig1 = Mockito.mock(SecurityAnalysisConfig.class); - ProcessConfig processConfig2 = Mockito.mock(LoadFlowConfig.class); - ProcessConfigHandler handler2 = Mockito.mock(ProcessConfigHandler.class); - - when(handler2.getProcessType()).thenReturn(ProcessType.LOADFLOW); - - processConfigService = new ProcessConfigService( - processConfigRepository, - List.of(handler, handler2) - ); when(processConfigRepository.findById(processConfigUuid1)).thenReturn(Optional.of(processConfigEntity1)); when(processConfigRepository.findById(processConfigUuid2)).thenReturn(Optional.of(processConfigEntity2)); when(processConfigEntity1.getProcessType()).thenReturn(ProcessType.SECURITY_ANALYSIS); - when(handler.toDto(processConfigEntity1)).thenReturn(processConfig1); when(processConfigEntity2.getProcessType()).thenReturn(ProcessType.LOADFLOW); - when(handler2.toDto(processConfigEntity2)).thenReturn(processConfig2); - when(processConfig1.compareWith(processConfig2)) - .thenThrow(new ClassCastException()); assertThatThrownBy(() -> processConfigService.compareProcessConfigs(processConfigUuid1, processConfigUuid2)) - .isInstanceOf(ClassCastException.class); + .isInstanceOf(MonitorServerException.class) + .satisfies(ex -> { + MonitorServerException e = (MonitorServerException) ex; + assertThat(e.getErrorCode()).isEqualTo(DIFFERENT_PROCESS_CONFIG_TYPE); + }); verify(processConfigRepository).findById(processConfigUuid1); verify(processConfigRepository).findById(processConfigUuid2); - verify(handler).toDto(processConfigEntity1); - verify(handler2).toDto(processConfigEntity2); - verify(processConfig1).compareWith(processConfig2); + verify(handler, never()).toDto(any()); } }