diff --git a/CHANGELOG.md b/CHANGELOG.md index 3f9d9f523..85e2b40f9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed - Changing from comparing strings to comparing uuids in `EntitySource.findFirstEntityByUuid` [#829](https://github.com/ie3-institute/PowerSystemDataModel/issues/829) - Adding JavaDoc to `EntitySource.safeMapGet` [#828](https://github.com/ie3-institute/PowerSystemDataModel/issues/828) +- Abstracting some methods in `ValidationUtils` [#852](https://github.com/ie3-institute/PowerSystemDataModel/issues/852) ## [4.1.0] - 2023-11-02 diff --git a/src/main/java/edu/ie3/datamodel/exceptions/DuplicateEntitiesException.java b/src/main/java/edu/ie3/datamodel/exceptions/DuplicateEntitiesException.java new file mode 100644 index 000000000..c8c2ac7da --- /dev/null +++ b/src/main/java/edu/ie3/datamodel/exceptions/DuplicateEntitiesException.java @@ -0,0 +1,27 @@ +/* + * © 2023. TU Dortmund University, + * Institute of Energy Systems, Energy Efficiency and Energy Economics, + * Research group Distribution grid planning and operation +*/ +package edu.ie3.datamodel.exceptions; + +import edu.ie3.datamodel.models.UniqueEntity; +import edu.ie3.datamodel.utils.ExceptionUtils; +import java.util.Collection; + +public class DuplicateEntitiesException extends ValidationException { + + protected DuplicateEntitiesException(String s) { + super(s); + } + + protected DuplicateEntitiesException(String s, String entities) { + super(s + entities); + } + + public DuplicateEntitiesException(String fieldName, Collection entities) { + this( + "The following entities have duplicate '" + fieldName + "': ", + ExceptionUtils.combine(entities)); + } +} diff --git a/src/main/java/edu/ie3/datamodel/utils/ExceptionUtils.java b/src/main/java/edu/ie3/datamodel/utils/ExceptionUtils.java index 018580d20..ebbaa61f8 100644 --- a/src/main/java/edu/ie3/datamodel/utils/ExceptionUtils.java +++ b/src/main/java/edu/ie3/datamodel/utils/ExceptionUtils.java @@ -5,7 +5,10 @@ */ package edu.ie3.datamodel.utils; +import edu.ie3.datamodel.models.UniqueEntity; +import java.util.Collection; import java.util.List; +import java.util.stream.Collectors; public class ExceptionUtils { private ExceptionUtils() { @@ -24,4 +27,16 @@ public static String getMessages(List exceptions) { .reduce("", (a, b) -> a + "\n " + b) .replaceFirst("\n ", ""); } + + /** + * Combines multiple {@link UniqueEntity} into a string. + * + * @param entities to be combined + * @return a string + */ + public static String combine(Collection entities) { + return "{" + + entities.stream().map(UniqueEntity::toString).collect(Collectors.joining(", ")) + + "}"; + } } diff --git a/src/main/java/edu/ie3/datamodel/utils/validation/GridContainerValidationUtils.java b/src/main/java/edu/ie3/datamodel/utils/validation/GridContainerValidationUtils.java index 1ef47aeb5..77388c6d4 100644 --- a/src/main/java/edu/ie3/datamodel/utils/validation/GridContainerValidationUtils.java +++ b/src/main/java/edu/ie3/datamodel/utils/validation/GridContainerValidationUtils.java @@ -5,10 +5,8 @@ */ package edu.ie3.datamodel.utils.validation; -import edu.ie3.datamodel.exceptions.InvalidEntityException; -import edu.ie3.datamodel.exceptions.InvalidGridException; -import edu.ie3.datamodel.exceptions.UnsafeEntityException; -import edu.ie3.datamodel.exceptions.ValidationException; +import edu.ie3.datamodel.exceptions.*; +import edu.ie3.datamodel.models.UniqueEntity; import edu.ie3.datamodel.models.input.AssetInput; import edu.ie3.datamodel.models.input.MeasurementUnitInput; import edu.ie3.datamodel.models.input.NodeInput; @@ -24,14 +22,6 @@ public class GridContainerValidationUtils extends ValidationUtils { - private static String duplicateUuidsString(String simpleName, Optional exceptionString) { - return "The provided entities in '" - + simpleName - + "' contains duplicate UUIDs. " - + "This is not allowed!\nDuplicated uuids:\n\n" - + exceptionString; - } - /** Private Constructor as this class is not meant to be instantiated */ private GridContainerValidationUtils() { throw new IllegalStateException("Don't try and instantiate a Utility class."); @@ -52,18 +42,10 @@ private GridContainerValidationUtils() { return List.of(isNull); } - List> exceptions = new ArrayList<>(); - /* sanity check to ensure distinct UUIDs */ - Optional exceptionString = - checkForDuplicateUuids(new HashSet<>(gridContainer.allEntitiesAsList())); - exceptions.add( - Try.ofVoid( - exceptionString.isPresent(), - () -> - new InvalidGridException( - duplicateUuidsString( - gridContainer.getClass().getSimpleName(), exceptionString)))); + List> exceptions = + new ArrayList<>( + checkForDuplicates(gridContainer.allEntitiesAsList(), UniqueEntity::getUuid)); exceptions.addAll(checkRawGridElements(gridContainer.getRawGrid())); exceptions.addAll( @@ -98,18 +80,10 @@ private GridContainerValidationUtils() { return List.of(isNull); } - List> exceptions = new ArrayList<>(); - /* sanity check to ensure distinct UUIDs */ - Optional exceptionString = - checkForDuplicateUuids(new HashSet<>(rawGridElements.allEntitiesAsList())); - exceptions.add( - Try.ofVoid( - exceptionString.isPresent(), - () -> - new InvalidGridException( - duplicateUuidsString( - rawGridElements.getClass().getSimpleName(), exceptionString)))); + List> exceptions = + new ArrayList<>( + checkForDuplicates(rawGridElements.allEntitiesAsList(), UniqueEntity::getUuid)); /* Checking nodes */ Set nodes = rawGridElements.getNodes(); @@ -183,18 +157,18 @@ private GridContainerValidationUtils() { * Checks the validity of type ids of every entity. * * @param rawGridElements the raw grid elements - * @return a list of try objects either containing an {@link UnsafeEntityException} or an empty - * Success + * @return a list of try objects either containing an {@link DuplicateEntitiesException} or an + * empty Success */ - protected static List> checkRawGridTypeIds( + protected static List> checkRawGridTypeIds( RawGridElements rawGridElements) { - List> exceptions = new ArrayList<>(); - exceptions.addAll(ValidationUtils.checkIds(rawGridElements.getNodes())); - exceptions.addAll(ValidationUtils.checkIds(rawGridElements.getLines())); - exceptions.addAll(ValidationUtils.checkIds(rawGridElements.getTransformer2Ws())); - exceptions.addAll(ValidationUtils.checkIds(rawGridElements.getTransformer3Ws())); - exceptions.addAll(ValidationUtils.checkIds(rawGridElements.getSwitches())); - exceptions.addAll(ValidationUtils.checkIds(rawGridElements.getMeasurementUnits())); + List> exceptions = new ArrayList<>(); + exceptions.addAll(checkForDuplicates(rawGridElements.getNodes(), AssetInput::getId)); + exceptions.addAll(checkForDuplicates(rawGridElements.getLines(), AssetInput::getId)); + exceptions.addAll(checkForDuplicates(rawGridElements.getTransformer2Ws(), AssetInput::getId)); + exceptions.addAll(checkForDuplicates(rawGridElements.getTransformer3Ws(), AssetInput::getId)); + exceptions.addAll(checkForDuplicates(rawGridElements.getSwitches(), AssetInput::getId)); + exceptions.addAll(checkForDuplicates(rawGridElements.getMeasurementUnits(), AssetInput::getId)); return exceptions; } @@ -217,19 +191,10 @@ protected static List> checkRawGridTypeIds( return List.of(isNull); } - List> exceptions = new ArrayList<>(); - // sanity check for distinct uuids - Optional exceptionString = - ValidationUtils.checkForDuplicateUuids( - new HashSet<>(systemParticipants.allEntitiesAsList())); - exceptions.add( - Try.ofVoid( - exceptionString.isPresent(), - () -> - new InvalidGridException( - duplicateUuidsString( - systemParticipants.getClass().getSimpleName(), exceptionString)))); + List> exceptions = + new ArrayList<>( + checkForDuplicates(systemParticipants.allEntitiesAsList(), UniqueEntity::getUuid)); exceptions.addAll(checkSystemParticipants(systemParticipants.getBmPlants(), nodes)); exceptions.addAll(checkSystemParticipants(systemParticipants.getChpPlants(), nodes)); @@ -274,23 +239,23 @@ protected static List> checkRawGridTypeIds( * Checks the validity of type ids of every entity. * * @param systemParticipants the system participants - * @return a list of try objects either containing an {@link UnsafeEntityException} or an empty - * Success + * @return a list of try objects either containing an {@link DuplicateEntitiesException} or an + * empty Success */ - protected static List> checkSystemParticipantsTypeIds( + protected static List> checkSystemParticipantsTypeIds( SystemParticipants systemParticipants) { - List> exceptions = new ArrayList<>(); - exceptions.addAll(ValidationUtils.checkIds(systemParticipants.getBmPlants())); - exceptions.addAll(ValidationUtils.checkIds(systemParticipants.getChpPlants())); - exceptions.addAll(ValidationUtils.checkIds(systemParticipants.getEvCS())); - exceptions.addAll(ValidationUtils.checkIds(systemParticipants.getEvs())); - exceptions.addAll(ValidationUtils.checkIds(systemParticipants.getFixedFeedIns())); - exceptions.addAll(ValidationUtils.checkIds(systemParticipants.getHeatPumps())); - exceptions.addAll(ValidationUtils.checkIds(systemParticipants.getLoads())); - exceptions.addAll(ValidationUtils.checkIds(systemParticipants.getPvPlants())); - exceptions.addAll(ValidationUtils.checkIds(systemParticipants.getStorages())); - exceptions.addAll(ValidationUtils.checkIds(systemParticipants.getWecPlants())); - exceptions.addAll(ValidationUtils.checkIds(systemParticipants.getEmSystems())); + List> exceptions = new ArrayList<>(); + exceptions.addAll(checkForDuplicates(systemParticipants.getBmPlants(), AssetInput::getId)); + exceptions.addAll(checkForDuplicates(systemParticipants.getChpPlants(), AssetInput::getId)); + exceptions.addAll(checkForDuplicates(systemParticipants.getEvCS(), AssetInput::getId)); + exceptions.addAll(checkForDuplicates(systemParticipants.getEvs(), AssetInput::getId)); + exceptions.addAll(checkForDuplicates(systemParticipants.getFixedFeedIns(), AssetInput::getId)); + exceptions.addAll(checkForDuplicates(systemParticipants.getHeatPumps(), AssetInput::getId)); + exceptions.addAll(checkForDuplicates(systemParticipants.getLoads(), AssetInput::getId)); + exceptions.addAll(checkForDuplicates(systemParticipants.getPvPlants(), AssetInput::getId)); + exceptions.addAll(checkForDuplicates(systemParticipants.getStorages(), AssetInput::getId)); + exceptions.addAll(checkForDuplicates(systemParticipants.getWecPlants(), AssetInput::getId)); + exceptions.addAll(checkForDuplicates(systemParticipants.getEmSystems(), AssetInput::getId)); return exceptions; } @@ -312,18 +277,10 @@ protected static List> checkSystemParticipantsT return List.of(isNull); } - List> exceptions = new ArrayList<>(); - // sanity check for distinct uuids - Optional exceptionString = - checkForDuplicateUuids(new HashSet<>(graphicElements.allEntitiesAsList())); - exceptions.add( - Try.ofVoid( - exceptionString.isPresent(), - () -> - new InvalidGridException( - duplicateUuidsString( - graphicElements.getClass().getSimpleName(), exceptionString)))); + List> exceptions = + new ArrayList<>( + checkForDuplicates(graphicElements.allEntitiesAsList(), UniqueEntity::getUuid)); graphicElements .getNodeGraphics() diff --git a/src/main/java/edu/ie3/datamodel/utils/validation/ValidationUtils.java b/src/main/java/edu/ie3/datamodel/utils/validation/ValidationUtils.java index c09607a0d..9cdd9add2 100644 --- a/src/main/java/edu/ie3/datamodel/utils/validation/ValidationUtils.java +++ b/src/main/java/edu/ie3/datamodel/utils/validation/ValidationUtils.java @@ -216,34 +216,6 @@ else if (SystemParticipantTypeInput.class.isAssignableFrom(assetTypeInput.getCla return exceptions; } - /** - * Checks the validity of the ids for a given set of {@link AssetInput}. - * - * @param inputs a set of asset inputs - * @return a list of try objects either containing an {@link UnsafeEntityException} or an empty - * Success - */ - protected static List> checkIds( - Set inputs) { - List ids = new ArrayList<>(); - List> exceptions = new ArrayList<>(); - - inputs.forEach( - input -> { - String id = input.getId(); - if (!ids.contains(id)) { - ids.add(id); - } else { - exceptions.add( - new Failure<>( - new UnsafeEntityException( - "There is already an entity with the id " + id, input))); - } - }); - - return exceptions; - } - /** * Checks, if the given object is null. If so, an {@link InvalidEntityException} wrapped in a * {@link Failure} is returned. @@ -327,20 +299,6 @@ protected static void detectMalformedQuantities( } } - /** - * Determines if the provided set only contains elements with distinct UUIDs - * - * @param entities the set that should be checked - * @return true if all UUIDs of the provided entities are unique, false otherwise - */ - private static boolean distinctUuids(Set entities) { - return entities.stream() - .filter(distinctByKey(UniqueEntity::getUuid)) - .collect(Collectors.toSet()) - .size() - == entities.size(); - } - /** * Predicate that can be used to filter elements based on a given Function * @@ -354,38 +312,38 @@ public static Predicate distinctByKey(Function keyExtractor } /** - * Checks if the provided set of unique entities only contains elements with distinct UUIDs and - * either returns a string with duplicated UUIDs or an empty optional otherwise. + * Method to check for duplicate fields in a set of {@link UniqueEntity}. * - * @param entities the entities that should be checkd for UUID uniqueness - * @return either a string wrapped in an optional with duplicate UUIDs or an empty optional + * @param entities to be checked + * @param supplier for the field + * @return a list of {@link Try}. + * @param type of the {@link UniqueEntity} + * @param type of the field */ - protected static Optional checkForDuplicateUuids(Set entities) { - if (distinctUuids(entities)) { - return Optional.empty(); - } - String duplicationsString = - entities.stream() - .collect(Collectors.groupingBy(UniqueEntity::getUuid, Collectors.counting())) - .entrySet() - .stream() - .filter(entry -> entry.getValue() > 1) - .map( - entry -> { - String duplicateEntitiesString = - entities.stream() - .filter(entity -> entity.getUuid().equals(entry.getKey())) - .map(UniqueEntity::toString) - .collect(Collectors.joining("\n - ")); - - return entry.getKey() - + ": " - + entry.getValue() - + "\n - " - + duplicateEntitiesString; - }) - .collect(Collectors.joining("\n\n")); + protected static + List> checkForDuplicates( + Collection entities, FieldSupplier supplier) { + Map> duplicates = + entities.stream().collect(Collectors.groupingBy(supplier::getField)); + + return duplicates.entrySet().stream() + .filter(e -> e.getValue().size() > 1) + .map( + duplicate -> + Failure.ofVoid( + new DuplicateEntitiesException( + duplicate.getKey().getClass().getSimpleName(), duplicate.getValue()))) + .collect(Collectors.toList()); + } - return Optional.of(duplicationsString); + /** + * Supplier for unique entity fields that returns a field of type F given an entity of type E. + * + * @param type of unique entity + * @param type of field + */ + @FunctionalInterface + protected interface FieldSupplier { + F getField(E entity); } } diff --git a/src/test/groovy/edu/ie3/datamodel/utils/validation/ValidationUtilsTest.groovy b/src/test/groovy/edu/ie3/datamodel/utils/validation/ValidationUtilsTest.groovy index 26c43982d..d6971bcb0 100644 --- a/src/test/groovy/edu/ie3/datamodel/utils/validation/ValidationUtilsTest.groovy +++ b/src/test/groovy/edu/ie3/datamodel/utils/validation/ValidationUtilsTest.groovy @@ -5,17 +5,12 @@ */ package edu.ie3.datamodel.utils.validation -import static edu.ie3.datamodel.models.StandardUnits.* -import static edu.ie3.datamodel.utils.validation.DummyAssetInput.invalid -import static edu.ie3.datamodel.utils.validation.DummyAssetInput.valid -import static edu.ie3.util.quantities.PowerSystemUnits.OHM_PER_KILOMETRE -import static edu.ie3.util.quantities.PowerSystemUnits.PU - +import edu.ie3.datamodel.exceptions.DuplicateEntitiesException import edu.ie3.datamodel.exceptions.FailedValidationException import edu.ie3.datamodel.exceptions.InvalidEntityException -import edu.ie3.datamodel.exceptions.UnsafeEntityException import edu.ie3.datamodel.exceptions.ValidationException import edu.ie3.datamodel.models.OperationTime +import edu.ie3.datamodel.models.UniqueEntity import edu.ie3.datamodel.models.input.AssetInput import edu.ie3.datamodel.models.input.NodeInput import edu.ie3.datamodel.models.input.OperatorInput @@ -31,6 +26,12 @@ import tech.units.indriya.quantity.Quantities import javax.measure.Quantity +import static edu.ie3.datamodel.models.StandardUnits.* +import static edu.ie3.datamodel.utils.validation.DummyAssetInput.invalid +import static edu.ie3.datamodel.utils.validation.DummyAssetInput.valid +import static edu.ie3.util.quantities.PowerSystemUnits.OHM_PER_KILOMETRE +import static edu.ie3.util.quantities.PowerSystemUnits.PU + class ValidationUtilsTest extends Specification { def "Smoke Test: Correct asset throws no exception"() { @@ -44,36 +45,15 @@ class ValidationUtilsTest extends Specification { noExceptionThrown() } - def "The validation utils should determine if a collection with UniqueEntity's is distinct by their uuid"() { - - expect: - ValidationUtils.distinctUuids(collection) == distinct - - where: - collection || distinct - [ - GridTestData.nodeF, - new NodeInput( - UUID.fromString("9e37ce48-9650-44ec-b888-c2fd182aff01"), "node_g", OperatorInput.NO_OPERATOR_ASSIGNED, - OperationTime.notLimited() - , - Quantities.getQuantity(1d, PU), - false, - null, - GermanVoltageLevelUtils.LV, - 6) - ] as Set || false - [ - GridTestData.nodeD, - GridTestData.nodeE - ] as Set || true - [] as Set || true - } - def "The validation utils should check for duplicates as expected"() { - expect: - ValidationUtils.checkForDuplicateUuids(collection) == checkResult + def tries = ValidationUtils.checkForDuplicates(collection, UniqueEntity::getUuid) + + if (!tries.isEmpty()) { + tries.get(0).exception.map { + it.message + } == checkResult + } where: collection || checkResult @@ -96,9 +76,9 @@ class ValidationUtilsTest extends Specification { null, GermanVoltageLevelUtils.LV, 6) - ] as Set || Optional.of("9e37ce48-9650-44ec-b888-c2fd182aff01: 2\n" + - " - NodeInput{uuid=9e37ce48-9650-44ec-b888-c2fd182aff01, id='node_f', operator=f15105c4-a2de-4ab8-a621-4bc98e372d92, operationTime=OperationTime{startDate=null, endDate=null, isLimited=false}, vTarget=1 p.u., slack=false, geoPosition=null, voltLvl=CommonVoltageLevel{id='Niederspannung', nominalVoltage=0.4 kV, synonymousIds=[Niederspannung, lv, ns], voltageRange=Interval [0.0 kV, 10 kV)}, subnet=6}\n" + - " - NodeInput{uuid=9e37ce48-9650-44ec-b888-c2fd182aff01, id='node_g', operator=f15105c4-a2de-4ab8-a621-4bc98e372d92, operationTime=OperationTime{startDate=null, endDate=null, isLimited=false}, vTarget=1 p.u., slack=false, geoPosition=null, voltLvl=CommonVoltageLevel{id='Niederspannung', nominalVoltage=0.4 kV, synonymousIds=[Niederspannung, lv, ns], voltageRange=Interval [0.0 kV, 10 kV)}, subnet=6}") + ] as Set || Optional.of("The following entities have duplicate 'UUID': " + + "{NodeInput{uuid=9e37ce48-9650-44ec-b888-c2fd182aff01, id='node_f', operator=f15105c4-a2de-4ab8-a621-4bc98e372d92, operationTime=OperationTime{startDate=null, endDate=null, isLimited=false}, vTarget=1 p.u., slack=false, geoPosition=null, voltLvl=CommonVoltageLevel{id='Niederspannung', nominalVoltage=0.4 kV, synonymousIds=[Niederspannung, lv, ns], voltageRange=Interval [0.0 kV, 10 kV)}, subnet=6}, " + + "NodeInput{uuid=9e37ce48-9650-44ec-b888-c2fd182aff01, id='node_g', operator=f15105c4-a2de-4ab8-a621-4bc98e372d92, operationTime=OperationTime{startDate=null, endDate=null, isLimited=false}, vTarget=1 p.u., slack=false, geoPosition=null, voltLvl=CommonVoltageLevel{id='Niederspannung', nominalVoltage=0.4 kV, synonymousIds=[Niederspannung, lv, ns], voltageRange=Interval [0.0 kV, 10 kV)}, subnet=6}}") [ GridTestData.nodeD, GridTestData.nodeE @@ -133,32 +113,32 @@ class ValidationUtilsTest extends Specification { GridTestData.nodeA.copy().id(null).build() || new InvalidEntityException("No ID assigned", invalidAsset) GridTestData.nodeA.copy().operationTime(null).build() || new InvalidEntityException("Operation time of the asset is not defined", invalidAsset) GridTestData.nodeA.copy().operationTime(OperationTime.builder(). - withStart(TimeUtil.withDefaults.toZonedDateTime("2020-03-26 15:11:31")). - withEnd(TimeUtil.withDefaults.toZonedDateTime("2020-03-25 15:11:31")).build()).build() || new InvalidEntityException("Operation start time of the asset has to be before end time", invalidAsset) + withStart(TimeUtil.withDefaults.toZonedDateTime("2020-03-26 15:11:31")). + withEnd(TimeUtil.withDefaults.toZonedDateTime("2020-03-25 15:11:31")).build()).build() || new InvalidEntityException("Operation start time of the asset has to be before end time", invalidAsset) } def "The check for negative entities should work as expected"() { given: def asset = new LineTypeInput( - UUID.fromString("3bed3eb3-9790-4874-89b5-a5434d408088"), - "lineType_AtoB", - Quantities.getQuantity(0d, SUSCEPTANCE_PER_LENGTH), - Quantities.getQuantity(0d, CONDUCTANCE_PER_LENGTH), - Quantities.getQuantity(0.437d, OHM_PER_KILOMETRE), - Quantities.getQuantity(0.356d, OHM_PER_KILOMETRE), - Quantities.getQuantity(300d, ELECTRIC_CURRENT_MAGNITUDE), - Quantities.getQuantity(20d, RATED_VOLTAGE_MAGNITUDE) - ) + UUID.fromString("3bed3eb3-9790-4874-89b5-a5434d408088"), + "lineType_AtoB", + Quantities.getQuantity(0d, SUSCEPTANCE_PER_LENGTH), + Quantities.getQuantity(0d, CONDUCTANCE_PER_LENGTH), + Quantities.getQuantity(0.437d, OHM_PER_KILOMETRE), + Quantities.getQuantity(0.356d, OHM_PER_KILOMETRE), + Quantities.getQuantity(300d, ELECTRIC_CURRENT_MAGNITUDE), + Quantities.getQuantity(20d, RATED_VOLTAGE_MAGNITUDE) + ) def invalidAsset = new LineTypeInput( - UUID.fromString("3bed3eb3-9790-4874-89b5-a5434d408088"), - "lineType_AtoB", - Quantities.getQuantity(-1d, SUSCEPTANCE_PER_LENGTH), // invalid value - Quantities.getQuantity(0d, CONDUCTANCE_PER_LENGTH), - Quantities.getQuantity(0.437d, OHM_PER_KILOMETRE), - Quantities.getQuantity(0.356d, OHM_PER_KILOMETRE), - Quantities.getQuantity(300d, ELECTRIC_CURRENT_MAGNITUDE), - Quantities.getQuantity(20d, RATED_VOLTAGE_MAGNITUDE) - ) + UUID.fromString("3bed3eb3-9790-4874-89b5-a5434d408088"), + "lineType_AtoB", + Quantities.getQuantity(-1d, SUSCEPTANCE_PER_LENGTH), // invalid value + Quantities.getQuantity(0d, CONDUCTANCE_PER_LENGTH), + Quantities.getQuantity(0.437d, OHM_PER_KILOMETRE), + Quantities.getQuantity(0.356d, OHM_PER_KILOMETRE), + Quantities.getQuantity(300d, ELECTRIC_CURRENT_MAGNITUDE), + Quantities.getQuantity(20d, RATED_VOLTAGE_MAGNITUDE) + ) when: ValidationUtils.detectNegativeQuantities([asset.getB()] as Quantity[], asset) @@ -177,25 +157,25 @@ class ValidationUtilsTest extends Specification { def "The check for zero or negative entities should work as expected"() { given: def asset = new LineTypeInput( - UUID.fromString("3bed3eb3-9790-4874-89b5-a5434d408088"), - "lineType_AtoB", - Quantities.getQuantity(1d, SUSCEPTANCE_PER_LENGTH), - Quantities.getQuantity(0d, CONDUCTANCE_PER_LENGTH), - Quantities.getQuantity(0.437d, OHM_PER_KILOMETRE), - Quantities.getQuantity(0.356d, OHM_PER_KILOMETRE), - Quantities.getQuantity(300d, ELECTRIC_CURRENT_MAGNITUDE), - Quantities.getQuantity(20d, RATED_VOLTAGE_MAGNITUDE) - ) + UUID.fromString("3bed3eb3-9790-4874-89b5-a5434d408088"), + "lineType_AtoB", + Quantities.getQuantity(1d, SUSCEPTANCE_PER_LENGTH), + Quantities.getQuantity(0d, CONDUCTANCE_PER_LENGTH), + Quantities.getQuantity(0.437d, OHM_PER_KILOMETRE), + Quantities.getQuantity(0.356d, OHM_PER_KILOMETRE), + Quantities.getQuantity(300d, ELECTRIC_CURRENT_MAGNITUDE), + Quantities.getQuantity(20d, RATED_VOLTAGE_MAGNITUDE) + ) def invalidAsset = new LineTypeInput( - UUID.fromString("3bed3eb3-9790-4874-89b5-a5434d408088"), - "lineType_AtoB", - Quantities.getQuantity(0d, SUSCEPTANCE_PER_LENGTH), // invalid value - Quantities.getQuantity(0d, CONDUCTANCE_PER_LENGTH), - Quantities.getQuantity(0.437d, OHM_PER_KILOMETRE), - Quantities.getQuantity(0.356d, OHM_PER_KILOMETRE), - Quantities.getQuantity(300d, ELECTRIC_CURRENT_MAGNITUDE), - Quantities.getQuantity(20d, RATED_VOLTAGE_MAGNITUDE) - ) + UUID.fromString("3bed3eb3-9790-4874-89b5-a5434d408088"), + "lineType_AtoB", + Quantities.getQuantity(0d, SUSCEPTANCE_PER_LENGTH), // invalid value + Quantities.getQuantity(0d, CONDUCTANCE_PER_LENGTH), + Quantities.getQuantity(0.437d, OHM_PER_KILOMETRE), + Quantities.getQuantity(0.356d, OHM_PER_KILOMETRE), + Quantities.getQuantity(300d, ELECTRIC_CURRENT_MAGNITUDE), + Quantities.getQuantity(20d, RATED_VOLTAGE_MAGNITUDE) + ) when: ValidationUtils.detectZeroOrNegativeQuantities([asset.getB()] as Quantity[], asset) @@ -259,10 +239,12 @@ class ValidationUtilsTest extends Specification { ] when: - List> exceptions = ValidationUtils.checkIds(validAssetIds) + List> exceptions = ValidationUtils.checkForDuplicates(validAssetIds, AssetInput::getId) then: - exceptions.every { ex -> ex.success } + exceptions.every { + ex -> ex.success + } } def "Duplicate asset input ids leads to an exception"() { @@ -273,11 +255,11 @@ class ValidationUtilsTest extends Specification { ] when: - List> exceptions = ValidationUtils.checkIds(invalidAssetIds) + List> exceptions = ValidationUtils.checkForDuplicates(invalidAssetIds, AssetInput::getId) then: exceptions.size() == 1 exceptions.get(0).failure - exceptions.get(0).exception.get().message.contains("Entity may be unsafe because of: There is already an entity with the id invalid_asset") + exceptions.get(0).exception.get().message.startsWith("The following entities have duplicate 'String': {AssetInput{uuid=") } }