From abee011cb9437bf50e21a559c3d0176d2abbf011 Mon Sep 17 00:00:00 2001 From: leventecsanyi Date: Wed, 19 Oct 2022 11:52:44 +0200 Subject: Improve code coverage - Fixed and refactored unit test to get over the 97% coverage baseline. - Removed unused exception. Issue-ID: CPS-475 Change-Id: I6dbcba58b880a584f6d9346e2aca6c763e5d2081 Signed-off-by: leventecsanyi --- ...NcmpDatastoreResourceRequestHandlerFactory.java | 3 +- .../rest/exceptions/CpsTaskExecutionException.java | 44 ------------ .../cps/ncmp/rest/mapper/CmHandleStateMapper.java | 2 - .../rest/mapper/CmHandleStateMapperSpec.groovy | 82 ++++++++++++++++++++++ .../rest/mapper/CmHandleStateMapperTest.groovy | 77 -------------------- .../CmHandleQueryRestParametersValidator.java | 25 +++---- ...CmHandleQueryRestParametersValidatorSpec.groovy | 5 ++ .../org/onap/cps/utils/JsonObjectMapperSpec.groovy | 17 ++++- 8 files changed, 116 insertions(+), 139 deletions(-) delete mode 100644 cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/exceptions/CpsTaskExecutionException.java create mode 100644 cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/mapper/CmHandleStateMapperSpec.groovy delete mode 100644 cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/mapper/CmHandleStateMapperTest.groovy diff --git a/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/handlers/NcmpDatastoreResourceRequestHandlerFactory.java b/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/handlers/NcmpDatastoreResourceRequestHandlerFactory.java index 35bd578ce2..7db754279c 100644 --- a/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/handlers/NcmpDatastoreResourceRequestHandlerFactory.java +++ b/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/handlers/NcmpDatastoreResourceRequestHandlerFactory.java @@ -55,10 +55,9 @@ public class NcmpDatastoreResourceRequestHandlerFactory { return new NcmpDatastorePassthroughRunningResourceRequestHandler(networkCmProxyDataService, cpsNcmpTaskExecutor, timeOutInMilliSeconds, notificationFeatureEnabled); case PASSTHROUGH_OPERATIONAL: + default: return new NcmpDatastorePassthroughOperationalResourceRequestHandler(networkCmProxyDataService, cpsNcmpTaskExecutor, timeOutInMilliSeconds, notificationFeatureEnabled); - default: - return null; } } } diff --git a/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/exceptions/CpsTaskExecutionException.java b/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/exceptions/CpsTaskExecutionException.java deleted file mode 100644 index 3e8929d2e3..0000000000 --- a/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/exceptions/CpsTaskExecutionException.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * Copyright (C) 2022 Nordix Foundation - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * SPDX-License-Identifier: Apache-2.0 - * ============LICENSE_END========================================================= - */ - -package org.onap.cps.ncmp.rest.exceptions; - -import lombok.Getter; - -public class CpsTaskExecutionException extends RuntimeException { - - private static final long serialVersionUID = 1481520410918497454L; - - @Getter - final String details; - - /** - * Constructor. - * - * @param message the error message - * @param details the error details - * @param cause the cause of the exception - */ - public CpsTaskExecutionException(final String message, final String details, final Throwable cause) { - super(message, cause); - this.details = details; - } - -} \ No newline at end of file diff --git a/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/mapper/CmHandleStateMapper.java b/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/mapper/CmHandleStateMapper.java index 097dd0af49..64a9934b99 100644 --- a/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/mapper/CmHandleStateMapper.java +++ b/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/mapper/CmHandleStateMapper.java @@ -62,9 +62,7 @@ public interface CmHandleStateMapper { dataStores.setOperational(operationalSyncState); } - return dataStores; - } /** diff --git a/cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/mapper/CmHandleStateMapperSpec.groovy b/cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/mapper/CmHandleStateMapperSpec.groovy new file mode 100644 index 0000000000..9a09b97973 --- /dev/null +++ b/cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/mapper/CmHandleStateMapperSpec.groovy @@ -0,0 +1,82 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2022 Nordix Foundation + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.cps.ncmp.rest.mapper + +import org.mapstruct.factory.Mappers +import org.onap.cps.ncmp.api.inventory.CmHandleState +import org.onap.cps.ncmp.api.inventory.CompositeStateBuilder +import org.onap.cps.ncmp.api.inventory.LockReasonCategory +import org.onap.cps.ncmp.rest.model.CmHandleCompositeState +import org.onap.cps.ncmp.api.inventory.DataStoreSyncState +import spock.lang.Specification + +import java.time.OffsetDateTime +import java.time.ZoneOffset +import java.time.format.DateTimeFormatter + +class CmHandleStateMapperSpec extends Specification { + + def formattedDateAndTime = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSZ") + .format(OffsetDateTime.of(2022, 12, 31, 20, 30, 40, 1, ZoneOffset.UTC)) + def objectUnderTest = Mappers.getMapper(CmHandleStateMapper) + + def 'Composite State to CmHandleCompositeState'() { + given: 'a composite state model' + def compositeState = new CompositeStateBuilder() + .withCmHandleState(CmHandleState.ADVISED) + .withLastUpdatedTime(formattedDateAndTime.toString()) + .withLockReason(LockReasonCategory.LOCKED_MODULE_SYNC_FAILED, 'locked details') + .withOperationalDataStores(DataStoreSyncState.SYNCHRONIZED, formattedDateAndTime).build() + compositeState.setDataSyncEnabled(false) + when: 'mapper is called' + def result = objectUnderTest.toCmHandleCompositeStateExternalLockReason(compositeState) + then: 'result is of the correct type' + assert result.class == CmHandleCompositeState.class + and: 'mapped result should have correct values' + assert !result.dataSyncEnabled + assert result.lastUpdateTime == formattedDateAndTime + assert result.lockReason.reason == 'LOCKED_MISBEHAVING' + assert result.lockReason.details == 'locked details' + assert result.cmHandleState == 'ADVISED' + assert result.dataSyncState.operational.getSyncState() != null + } + + def 'Handling null state.'() { + expect: 'converting null returns null' + objectUnderTest.toDataStores(null) == null + } + + def 'Internal to External Lock Reason Mapping of #scenario'() { + given: 'a LOCKED composite state with locked reason of #scenario' + def compositeState = new CompositeStateBuilder() + .withCmHandleState(CmHandleState.LOCKED) + .withLockReason(lockReason, '').build() + when: 'the composite state is mapped to a CMHandle composite state' + def result = objectUnderTest.toCmHandleCompositeStateExternalLockReason(compositeState) + then: 'the composite state contains the expected lock Reason and details' + result.getLockReason().getReason() == expectedExternalLockReason + where: + scenario | lockReason || expectedExternalLockReason + 'LOCKED_MODULE_SYNC_FAILED' | LockReasonCategory.LOCKED_MODULE_SYNC_FAILED || 'LOCKED_MISBEHAVING' + 'null value' | null || null + } + +} diff --git a/cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/mapper/CmHandleStateMapperTest.groovy b/cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/mapper/CmHandleStateMapperTest.groovy deleted file mode 100644 index 663b9d02a6..0000000000 --- a/cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/mapper/CmHandleStateMapperTest.groovy +++ /dev/null @@ -1,77 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * Copyright (C) 2022 Nordix Foundation - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * SPDX-License-Identifier: Apache-2.0 - * ============LICENSE_END========================================================= - */ - -package org.onap.cps.ncmp.rest.mapper - -import org.mapstruct.factory.Mappers -import org.onap.cps.ncmp.api.inventory.CmHandleState -import org.onap.cps.ncmp.api.inventory.CompositeStateBuilder -import org.onap.cps.ncmp.api.inventory.LockReasonCategory -import org.onap.cps.ncmp.rest.model.CmHandleCompositeState -import org.onap.cps.ncmp.api.inventory.DataStoreSyncState -import spock.lang.Specification - -import java.time.OffsetDateTime -import java.time.ZoneOffset -import java.time.format.DateTimeFormatter - -class CmHandleStateMapperTest extends Specification { - - def formattedDateAndTime = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSZ") - .format(OffsetDateTime.of(2022, 12, 31, 20, 30, 40, 1, ZoneOffset.UTC)) - def objectUnderTest = Mappers.getMapper(CmHandleStateMapper) - - def 'Composite State to CmHandleCompositeState'() { - given: 'a composite state model' - def compositeState = new CompositeStateBuilder() - .withCmHandleState(CmHandleState.ADVISED) - .withLastUpdatedTime(formattedDateAndTime.toString()) - .withLockReason(LockReasonCategory.LOCKED_MODULE_SYNC_FAILED, 'locked details') - .withOperationalDataStores(DataStoreSyncState.SYNCHRONIZED, formattedDateAndTime).build() - compositeState.setDataSyncEnabled(false) - when: 'mapper is called' - def result = objectUnderTest.toCmHandleCompositeStateExternalLockReason(compositeState) - then: 'result is of the correct type' - assert result.class == CmHandleCompositeState.class - and: 'mapped result should have correct values' - assert !result.dataSyncEnabled - assert result.lastUpdateTime == formattedDateAndTime - assert result.lockReason.reason == 'LOCKED_MISBEHAVING' - assert result.lockReason.details == 'locked details' - assert result.cmHandleState == 'ADVISED' - assert result.dataSyncState.operational.getSyncState() != null - } - - def 'Internal to External Lock Reason Mapping of #scenario'() { - given: 'a LOCKED composite state with locked reason of #scenario' - def compositeState = new CompositeStateBuilder() - .withCmHandleState(CmHandleState.LOCKED) - .withLockReason(lockReason, '').build() - when: 'the composite state is mapped to a CMHandle composite state' - def result = objectUnderTest.toCmHandleCompositeStateExternalLockReason(compositeState) - then: 'the composite state contains the expected lock Reason and details' - result.getLockReason().getReason() == expectedExternalLockReason - where: - scenario | lockReason || expectedExternalLockReason - 'LOCKED_MODULE_SYNC_FAILED' | LockReasonCategory.LOCKED_MODULE_SYNC_FAILED || 'LOCKED_MISBEHAVING' - 'null value' | null || null - } - -} diff --git a/cps-service/src/main/java/org/onap/cps/utils/CmHandleQueryRestParametersValidator.java b/cps-service/src/main/java/org/onap/cps/utils/CmHandleQueryRestParametersValidator.java index 7fe47be2da..4d0eb7d412 100644 --- a/cps-service/src/main/java/org/onap/cps/utils/CmHandleQueryRestParametersValidator.java +++ b/cps-service/src/main/java/org/onap/cps/utils/CmHandleQueryRestParametersValidator.java @@ -42,16 +42,16 @@ public class CmHandleQueryRestParametersValidator { cmHandleQueryServiceParameters.getCmHandleQueryParameters().forEach( conditionApiProperty -> { if (Strings.isNullOrEmpty(conditionApiProperty.getConditionName())) { - throwDataValidationException("Missing 'conditionName' - please supply a valid name."); + throw createDataValidationException("Missing 'conditionName' - please supply a valid name."); } if (Arrays.stream(ValidQueryProperties.values()).noneMatch(validQueryProperty -> validQueryProperty.getQueryProperty().equals(conditionApiProperty.getConditionName()))) { - throwDataValidationException( + throw createDataValidationException( String.format("Wrong 'conditionName': %s - please supply a valid name.", conditionApiProperty.getConditionName())); } if (conditionApiProperty.getConditionParameters().isEmpty()) { - throwDataValidationException( + throw createDataValidationException( "Empty 'conditionsParameters' - please supply a valid condition parameter."); } conditionApiProperty.getConditionParameters().forEach( @@ -63,16 +63,16 @@ public class CmHandleQueryRestParametersValidator { private static void validateConditionParameter(final Map conditionParameter) { if (conditionParameter.isEmpty()) { - throwDataValidationException( + throw createDataValidationException( "Empty 'conditionsParameter' - please supply a valid condition parameter."); } if (conditionParameter.size() > 1) { - throwDataValidationException("Too many name in one 'conditionsParameter' -" + throw createDataValidationException("Too many name in one 'conditionsParameter' -" + " please supply one name in one condition parameter."); } conditionParameter.forEach((key, value) -> { if (Strings.isNullOrEmpty(key)) { - throwDataValidationException( + throw createDataValidationException( "Missing 'conditionsParameterName' - please supply a valid name."); } }); @@ -86,7 +86,8 @@ public class CmHandleQueryRestParametersValidator { if (conditionProperty.containsKey("moduleName") && !conditionProperty.get("moduleName").isEmpty()) { return; } - throwDataValidationException("Wrong module condition property. - please supply a valid condition property."); + throw createDataValidationException("Wrong module condition property. - " + + "please supply a valid condition property."); } /** @@ -98,15 +99,15 @@ public class CmHandleQueryRestParametersValidator { return true; } if (conditionProperty.size() > 1) { - throwDataValidationException("Only one condition property is allowed for the CPS path query."); + throw createDataValidationException("Only one condition property is allowed for the CPS path query."); } if (!conditionProperty.containsKey("cpsPath")) { - throwDataValidationException( + throw createDataValidationException( "Wrong CPS path condition property. - expecting \"cpsPath\" as the condition property."); } final String cpsPath = conditionProperty.get("cpsPath"); if (cpsPath.isBlank()) { - throwDataValidationException( + throw createDataValidationException( "Wrong CPS path. - please supply a valid CPS path."); } if (cpsPath.contains("/additional-properties")) { @@ -117,8 +118,8 @@ public class CmHandleQueryRestParametersValidator { return true; } - private static void throwDataValidationException(final String details) { - throw new DataValidationException("Invalid Query Parameter.", details); + private static DataValidationException createDataValidationException(final String details) { + return new DataValidationException("Invalid Query Parameter.", details); } } diff --git a/cps-service/src/test/groovy/org/onap/cps/utils/CmHandleQueryRestParametersValidatorSpec.groovy b/cps-service/src/test/groovy/org/onap/cps/utils/CmHandleQueryRestParametersValidatorSpec.groovy index d5dcb7fc5c..c40ffa9a35 100644 --- a/cps-service/src/test/groovy/org/onap/cps/utils/CmHandleQueryRestParametersValidatorSpec.groovy +++ b/cps-service/src/test/groovy/org/onap/cps/utils/CmHandleQueryRestParametersValidatorSpec.groovy @@ -103,6 +103,11 @@ class CmHandleQueryRestParametersValidatorSpec extends Specification { 'cpsPath not supplied' | ['cpsPath':''] || 'Wrong CPS path. - please supply a valid CPS path.' } + def 'No conditions.'() { + expect: 'no conditions always returns true' + CmHandleQueryRestParametersValidator.validateCpsPathConditionProperties([:]) == true + } + def 'Validate CmHandle where #scenario.'() { when: 'the validator is called on a cps path condition property' def result = CmHandleQueryRestParametersValidator.validateCpsPathConditionProperties(['cpsPath':cpsPath]) diff --git a/cps-service/src/test/groovy/org/onap/cps/utils/JsonObjectMapperSpec.groovy b/cps-service/src/test/groovy/org/onap/cps/utils/JsonObjectMapperSpec.groovy index 461014418e..e205a19eed 100644 --- a/cps-service/src/test/groovy/org/onap/cps/utils/JsonObjectMapperSpec.groovy +++ b/cps-service/src/test/groovy/org/onap/cps/utils/JsonObjectMapperSpec.groovy @@ -20,7 +20,7 @@ package org.onap.cps.utils - +import com.fasterxml.jackson.core.JsonProcessingException import com.fasterxml.jackson.databind.ObjectMapper import com.fasterxml.jackson.databind.SerializationFeature import groovy.json.JsonSlurper @@ -44,6 +44,19 @@ class JsonObjectMapperSpec extends Specification { assert contentMap.'test:bookstore'.'bookstore-name' == 'Chapters' } + def 'Map a structured object to json String error.'() { + given: 'some object' + def object = new Object() + and: 'the Object mapper throws an exception' + spiedObjectMapper.writeValueAsString(object) >> { throw new JsonProcessingException('Sample problem'){} } + when: 'attempting to convert the object to a string' + jsonObjectMapper.asJsonString(object); + then: 'a Data Validation Exception is thrown' + def thrown = thrown(DataValidationException) + and: 'the details containing the original error message' + assert thrown.details == 'Sample problem' + } + def 'Map a structurally compatible object to class object of specific class type T.'() { given: 'a map object model' def contentMap = new JsonSlurper().parseText(TestUtils.getResourceFileContent('bookstore.json')) @@ -61,7 +74,7 @@ class JsonObjectMapperSpec extends Specification { given: 'Unstructured json string' def content = '{ "nest": { "birds": "bird"] } }' when: 'mapping json string to given class type' - def contentMap = jsonObjectMapper.convertJsonString(content, Map); + jsonObjectMapper.convertJsonString(content, Map); then: 'an exception is thrown' thrown(DataValidationException) } -- cgit 1.2.3-korg