[AAI] Improve test coverage for A&AI component aai-schema-service 74/141274/2
authoraditi.shukla@t-systems.com <aditi.shukla@t-systems.com>
Fri, 13 Jun 2025 11:43:07 +0000 (13:43 +0200)
committerakshay.khairnar@t-systems.com <akshay.khairnar@t-systems.com>
Mon, 16 Jun 2025 13:13:21 +0000 (15:13 +0200)
- to Improve test coverage for A&AI component aai-schema-service <=80%
Issue-ID: AAI-4107
Change-Id: I72de90f0621dd9c32e23b42f1e495e4b15e6c2c4
Signed-off-by: akshay.khairnar@t-systems.com <akshay.khairnar@t-systems.com>
aai-queries/pom.xml
aai-queries/src/test/java/org/onap/aai/queries/GetCustomQueryConfigTest.java [new file with mode: 0644]
aai-queries/src/test/java/org/onap/aai/queries/GremlinServerSingletonTest.java [new file with mode: 0644]
aai-schema-service/src/test/java/org/onap/aai/schemaservice/SchemaServiceTest.java
aai-schema-service/src/test/java/org/onap/aai/schemaservice/config/AAIConfigTranslatorTest.java [new file with mode: 0644]

index 062db8d..e7df473 100644 (file)
             <artifactId>junit-jupiter-params</artifactId>
             <scope>test</scope>
         </dependency>
+        <dependency>
+            <groupId>org.projectlombok</groupId>
+            <artifactId>lombok</artifactId>
+            <version>1.18.30</version>
+            <scope>provided</scope>
+        </dependency>
     </dependencies>
     <build>
         <plugins>
diff --git a/aai-queries/src/test/java/org/onap/aai/queries/GetCustomQueryConfigTest.java b/aai-queries/src/test/java/org/onap/aai/queries/GetCustomQueryConfigTest.java
new file mode 100644 (file)
index 0000000..77e8db1
--- /dev/null
@@ -0,0 +1,196 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright © 2025 Deutsche Telekom. All rights reserved.
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+package org.onap.aai.queries;
+
+import static org.junit.jupiter.api.Assertions.*;
+import com.google.common.collect.Lists;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonNull;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonPrimitive;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+
+public class GetCustomQueryConfigTest {
+
+    private String configJson;
+
+    private GetCustomQueryConfig getCustomQueryConfig;
+
+
+    @BeforeEach
+    public void setUp() throws Exception {
+        System.setProperty("AJSC_HOME", ".");
+        System.setProperty("BUNDLECONFIG_DIR", "src/main/resources");
+
+        configJson = "{\n\t\"stored-queries\": [{\n"
+            + "\t\t\"queryName1\": {\n\t\t\t\"query\": {\n\t\t\t\t\"required-properties\": [\"prop1\", \"prop2\"],\n\t\t\t\t\"optional-properties\": [\"prop3\", \"prop4\"]\n\t\t\t},\n\t\t\t\"stored-query\": \"out('blah').has('something','foo')\"\n\t\t}\n\t}, {\n"
+            + "\t\t\"queryName2\": {\n\t\t\t\"query\": {\n\t\t\t\t\"optional-properties\": [\"prop5\"]\n\t\t\t},\n\t\t\t\"stored-query\": \"out('bar').has('stuff','baz')\"\n\t\t}\n\t}, {\n"
+            + "\t\t\"queryName3\": {\n\t\t\t\"stored-query\": \"out('bar1').has('stuff','baz1')\"\n\t\t}\n\t}]\n}";
+
+        getCustomQueryConfig = new GetCustomQueryConfig(configJson);
+
+    }
+
+    @Test
+    public void testGetStoredQueryNameWithOptAndReqProps() {
+        GetCustomQueryConfig getCustomQueryConfig = new GetCustomQueryConfig(configJson);
+        CustomQueryConfig cqc = getCustomQueryConfig.getStoredQuery("queryName1");
+
+        assertEquals(Lists.newArrayList("prop3", "prop4"), cqc.getQueryOptionalProperties());
+        assertEquals(Lists.newArrayList("prop1", "prop2"), cqc.getQueryRequiredProperties());
+        assertEquals("out('blah').has('something','foo')", cqc.getQuery());
+    }
+
+    @Test
+    public void testGetStoredQueryNameWithOptProps() {
+        GetCustomQueryConfig getCustomQueryConfig = new GetCustomQueryConfig(configJson);
+        CustomQueryConfig cqc = getCustomQueryConfig.getStoredQuery("queryName2");
+
+        assertEquals(Lists.newArrayList("prop5"), cqc.getQueryOptionalProperties());
+        assertEquals(new ArrayList<String>(), cqc.getQueryRequiredProperties());
+        assertEquals("out('bar').has('stuff','baz')", cqc.getQuery());
+    }
+
+    @Test
+    public void testGetStoredQueryNameWithNoProps() {
+        GetCustomQueryConfig getCustomQueryConfig = new GetCustomQueryConfig(configJson);
+        CustomQueryConfig cqc = getCustomQueryConfig.getStoredQuery("queryName3");
+
+        assertEquals(new ArrayList<String>(), cqc.getQueryOptionalProperties());
+        assertEquals(new ArrayList<String>(), cqc.getQueryRequiredProperties());
+        assertEquals("out('bar1').has('stuff','baz1')", cqc.getQuery());
+    }
+
+    @Test
+    public void testGetPropertyString() throws Exception {
+        // Accessing the private method using reflection
+        Method method = GetCustomQueryConfig.class.getDeclaredMethod("getPropertyString", JsonObject.class, String.class);
+        method.setAccessible(true); // Make the private method accessible
+
+        // Prepare test data for the JSON
+        JsonObject configObject = new JsonObject();
+        JsonElement queryName1 = new JsonPrimitive("out('blah').has('something','foo')");
+        configObject.add("queryName1", queryName1);
+
+        // Test case 1: The config is present and valid
+        String result = (String) method.invoke(getCustomQueryConfig, configObject, "queryName1");
+        assertEquals("out('blah').has('something','foo')", result);
+
+        // Test case 2: The config is not present in the JSON
+        result = (String) method.invoke(getCustomQueryConfig, configObject, "nonExistingConfig");
+        assertNull(result);
+
+        // Test case 3: The config is null
+        configObject.add("queryName2", JsonNull.INSTANCE);
+        result = (String) method.invoke(getCustomQueryConfig, configObject, "queryName2");
+        assertNull(result);
+    }
+
+    @Test
+    public void testQueryWithNullProperties() {
+        String queryWithNullPropsJson = "{\n"
+            + "\"stored-queries\": [{\n"
+            + "\t\"queryName1\": {\n"
+            + "\t\t\"query\": {\n"
+            + "\t\t\t\"required-properties\": null,\n"
+            + "\t\t\t\"optional-properties\": null\n"
+            + "\t\t},\n"
+            + "\t\t\"stored-query\": \"out('blah').has('something','foo')\"\n"
+            + "\t}\n"
+            + "}]\n"
+            + "}";
+
+        GetCustomQueryConfig getCustomQueryConfig = new GetCustomQueryConfig(queryWithNullPropsJson);
+        CustomQueryConfig cqc = getCustomQueryConfig.getStoredQuery("queryName1");
+
+        // Assert that null values for required/optional properties are converted to empty lists
+        assertEquals(new ArrayList<String>(), cqc.getQueryRequiredProperties());
+        assertEquals(new ArrayList<String>(), cqc.getQueryOptionalProperties());
+    }
+
+    @Test
+    public void testQueryWithMissingProperties() {
+        String queryWithMissingPropsJson = "{\n"
+            + "\"stored-queries\": [{\n"
+            + "\t\"queryName1\": {\n"
+            + "\t\t\"query\": {\n"
+            + "\t\t\t\"required-properties\": []\n"
+            + "\t\t},\n"
+            + "\t\t\"stored-query\": \"out('blah').has('something','foo')\"\n"
+            + "\t}\n"
+            + "}]\n"
+            + "}";
+
+        GetCustomQueryConfig getCustomQueryConfig = new GetCustomQueryConfig(queryWithMissingPropsJson);
+        CustomQueryConfig cqc = getCustomQueryConfig.getStoredQuery("queryName1");
+
+        // Since "optional-properties" is missing, it should default to an empty list
+        assertEquals(new ArrayList<String>(), cqc.getQueryOptionalProperties());
+        assertEquals(new ArrayList<String>(), cqc.getQueryRequiredProperties());
+    }
+
+    @Test
+    public void testQueryWithNullRequiredProperties() {
+        String queryWithNullPropsJson = "{\n"
+            + "\"stored-queries\": [{\n"
+            + "\t\"queryName1\": {\n"
+            + "\t\t\"query\": {\n"
+            + "\t\t\t\"required-properties\": null,\n"  // Null for required properties
+            + "\t\t\t\"optional-properties\": [\"prop3\"]\n"
+            + "\t\t},\n"
+            + "\t\t\"stored-query\": \"out('blah').has('something','foo')\"\n"
+            + "\t}\n"
+            + "}]\n"
+            + "}";
+
+        GetCustomQueryConfig getCustomQueryConfig = new GetCustomQueryConfig(queryWithNullPropsJson);
+        CustomQueryConfig cqc = getCustomQueryConfig.getStoredQuery("queryName1");
+
+        // Assert that null values for required-properties convert to an empty list
+        assertEquals(new ArrayList<String>(), cqc.getQueryRequiredProperties());
+        assertEquals(Lists.newArrayList("prop3"), cqc.getQueryOptionalProperties());
+    }
+
+    @Test
+    public void testQueryWithNullOptionalProperties() {
+        String queryWithNullPropsJson = "{\n"
+            + "\"stored-queries\": [{\n"
+            + "\t\"queryName1\": {\n"
+            + "\t\t\"query\": {\n"
+            + "\t\t\t\"required-properties\": [\"prop1\"],\n"
+            + "\t\t\t\"optional-properties\": null  // Null for optional properties\n"
+            + "\t\t},\n"
+            + "\t\t\"stored-query\": \"out('blah').has('something','foo')\"\n"
+            + "\t}\n"
+            + "}]\n"
+            + "}";
+
+        GetCustomQueryConfig getCustomQueryConfig = new GetCustomQueryConfig(queryWithNullPropsJson);
+        CustomQueryConfig cqc = getCustomQueryConfig.getStoredQuery("queryName1");
+
+        // Assert that null values for optional-properties convert to an empty list
+        assertEquals(Lists.newArrayList("prop1"), cqc.getQueryRequiredProperties());
+        assertEquals(new ArrayList<String>(), cqc.getQueryOptionalProperties());
+    }
+}
diff --git a/aai-queries/src/test/java/org/onap/aai/queries/GremlinServerSingletonTest.java b/aai-queries/src/test/java/org/onap/aai/queries/GremlinServerSingletonTest.java
new file mode 100644 (file)
index 0000000..97f65d2
--- /dev/null
@@ -0,0 +1,130 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright © 2025 Deutsche Telekom. All rights reserved.
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+package org.onap.aai.queries;
+
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.mockito.Mockito;
+
+import java.io.FileWriter;
+import java.io.IOException;
+import lombok.SneakyThrows;
+import java.lang.reflect.Field;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
+import static org.junit.jupiter.api.Assertions.*;
+import static org.mockito.Mockito.*;
+
+public class GremlinServerSingletonTest {
+
+    private GremlinServerSingleton gremlinServerSingleton;
+    private GetCustomQueryConfig mockQueryConfig;
+    private CustomQueryConfig mockCustomQueryConfig;
+    private Path storedQueriesFilePath;  // To store the dynamic path of the temporary file
+    private static final String TEST_KEY = "testKey";
+    private static final String TEST_QUERY = "MATCH (n) RETURN n";
+
+    @BeforeEach
+    @SneakyThrows
+    public void setUp() {
+        // Create a temporary directory to store test files
+        Path tempDir = Files.createTempDirectory("testDir");
+        storedQueriesFilePath = tempDir.resolve("stored-queries.json");
+
+        // Create the necessary directories
+        Files.createDirectories(storedQueriesFilePath.getParent());
+
+        // Write the mock query data to the temporary file
+        FileWriter fileWriter = new FileWriter(storedQueriesFilePath.toFile());
+        fileWriter.write("{\"query\": \"" + TEST_QUERY + "\"}");
+        fileWriter.close();
+
+        // Mock dependencies
+        mockQueryConfig = mock(GetCustomQueryConfig.class);
+        mockCustomQueryConfig = mock(CustomQueryConfig.class);
+
+        when(mockQueryConfig.getStoredQuery(TEST_KEY)).thenReturn(mockCustomQueryConfig);
+        when(mockCustomQueryConfig.getQuery()).thenReturn(TEST_QUERY);
+
+        // Spy on GremlinServerSingleton to mock the initialization
+        GremlinServerSingleton spyGremlinServerSingleton = spy(new GremlinServerSingleton());
+
+        // Inject the mock using reflection
+        setPrivateField(spyGremlinServerSingleton, "queryConfig", mockQueryConfig);
+
+        // Use the spy instance
+        gremlinServerSingleton = spyGremlinServerSingleton;
+    }
+
+
+    @Test
+    public void testGetStoredQueryFromConfig_QueryExists() {
+        // Call the method with a valid key
+        String query = gremlinServerSingleton.getStoredQueryFromConfig(TEST_KEY);
+
+        // Assert that the query is returned as expected
+        assertNotNull(query);
+        assertEquals(TEST_QUERY, query);
+    }
+
+    @Test
+    public void testGetCustomQueryConfig_QueryExists() {
+        // Call the method with a valid key
+        CustomQueryConfig result = gremlinServerSingleton.getCustomQueryConfig(TEST_KEY);
+
+        // Assert that the result is the mock CustomQueryConfig
+        assertNotNull(result);
+        assertEquals(mockCustomQueryConfig, result);
+    }
+
+    @SneakyThrows
+    private void setPrivateField(Object target, String fieldName, Object value) {
+        Class<?> targetClass = target.getClass();
+        Field field = null;
+
+        // Traverse class hierarchy to find the field
+        while (targetClass != null) {
+            try {
+                field = targetClass.getDeclaredField(fieldName);
+                break; // Stop if found
+            } catch (NoSuchFieldException e) {
+                targetClass = targetClass.getSuperclass(); // Move to parent
+            }
+        }
+
+        if (field != null) {
+            field.setAccessible(true);
+            field.set(target, value);
+        } else {
+            throw new NoSuchFieldException("Field " + fieldName + " not found in class hierarchy.");
+        }
+    }
+
+    // Optionally clean up the temporary files after the test run
+    @AfterEach
+    public void tearDown() throws IOException {
+        // Delete the temporary file and directory
+        Files.deleteIfExists(storedQueriesFilePath);
+        Files.deleteIfExists(storedQueriesFilePath.getParent());
+    }
+}
index 2188a15..e4ab714 100644 (file)
@@ -30,6 +30,7 @@ import java.util.Collections;
 import org.junit.jupiter.api.BeforeAll;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
+import static org.junit.jupiter.api.Assertions.*;
 import org.onap.aai.exceptions.AAIException;
 import org.onap.aai.util.AAIConfig;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -169,4 +170,64 @@ public class SchemaServiceTest {
         assertThat(responseEntity.getStatusCodeValue(), is(200));
 
     }
+
+    @Test
+    public void testSetDefaultProps() {
+        // Simulate directory containing app name
+        System.setProperty("user.dir", "/path/to/aai-schema-service");
+        System.clearProperty("BUNDLECONFIG_DIR");
+
+        // Call setDefaultProps
+        SchemaServiceApp.setDefaultProps();
+
+        // Verify the BUNDLECONFIG_DIR property is set correctly
+        assertEquals("src/main/resources", System.getProperty("BUNDLECONFIG_DIR"));
+
+        // Simulate directory not containing app name
+        System.setProperty("user.dir", "/path/to/other");
+        System.clearProperty("BUNDLECONFIG_DIR");
+        SchemaServiceApp.setDefaultProps();
+
+        // Verify the default value when not containing the app name
+        assertEquals("aai-schema-service/src/main/resources", System.getProperty("BUNDLECONFIG_DIR"));
+    }
+
+    @Test
+    public void testSetDefaultPropsWhenNotSet() {
+        // Simulate directory not containing app name
+        System.setProperty("user.dir", "/path/to/other");
+        System.clearProperty("BUNDLECONFIG_DIR");
+
+        // Call setDefaultProps
+        SchemaServiceApp.setDefaultProps();
+
+        // Verify the default value when the property was not previously set
+        assertEquals("aai-schema-service/src/main/resources", System.getProperty("BUNDLECONFIG_DIR"));
+    }
+
+    // Test for setDefaultProps with null file.separator
+    @Test
+    public void testSetDefaultPropsWithNullFileSeparator() {
+        // Clear the file.separator property
+        System.clearProperty("file.separator");
+
+        // Call setDefaultProps to set the default value
+        SchemaServiceApp.setDefaultProps();
+
+        // Verify that the file.separator system property is set to "/"
+        assertEquals("/", System.getProperty("file.separator"));
+    }
+
+    @Test
+    public void testAJSCHomePropertyWhenNotSet() {
+        // Clear the AJSC_HOME property to simulate it being unset
+        System.clearProperty("AJSC_HOME");
+
+        // Call setDefaultProps to ensure AJSC_HOME gets set
+        SchemaServiceApp.setDefaultProps();
+
+        // Verify that the AJSC_HOME property is set to "."
+        assertEquals(".", System.getProperty("AJSC_HOME"));
+    }
+
 }
diff --git a/aai-schema-service/src/test/java/org/onap/aai/schemaservice/config/AAIConfigTranslatorTest.java b/aai-schema-service/src/test/java/org/onap/aai/schemaservice/config/AAIConfigTranslatorTest.java
new file mode 100644 (file)
index 0000000..1dae19c
--- /dev/null
@@ -0,0 +1,118 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright © 2025 Deutsche Telekom. All rights reserved.
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+package org.onap.aai.schemaservice.config;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.onap.aai.schemaservice.nodeschema.SchemaVersion;
+import org.onap.aai.schemaservice.nodeschema.SchemaVersions;
+
+
+import java.io.File;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+import static org.junit.jupiter.api.Assertions.*;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+
+class AAIConfigTranslatorTest {
+
+    private AAIConfigTranslator configTranslator;
+    private SchemaLocationsBean mockSchemaLocationsBean;
+    private SchemaVersion mockSchemaVersion;
+    private SchemaVersions mockSchemaVersions;
+
+    @BeforeEach
+    void setUp() {
+        mockSchemaLocationsBean = mock(SchemaLocationsBean.class);
+        mockSchemaVersions = mock(SchemaVersions.class);
+        mockSchemaVersion = mock(SchemaVersion.class);
+
+        when(mockSchemaVersions.getVersions()).thenReturn(List.of(mockSchemaVersion));
+        when(mockSchemaVersion.toString()).thenReturn("v1");
+
+        configTranslator = new AAIConfigTranslator(mockSchemaLocationsBean,mockSchemaVersions);
+    }
+
+
+    @Test
+    void testGetEdgeFiles_noFilesFound() {
+        // Mock the schema locations
+        String mockEdgeDirectory = "mock/edge/directory";
+        when(mockSchemaLocationsBean.getEdgeDirectory()).thenReturn(mockEdgeDirectory);
+        when(mockSchemaLocationsBean.getEdgesInclusionPattern()).thenReturn(List.of(".*\\.edge"));
+        when(mockSchemaLocationsBean.getEdgesExclusionPattern()).thenReturn(Collections.emptyList());
+
+        // Mock SchemaVersion
+        when(mockSchemaVersion.toString()).thenReturn("v1");
+
+        // Mock File behavior for the version directory
+        File mockVersionDirectory = mock(File.class);
+
+        // Simulate the behavior of an empty directory
+        when(mockVersionDirectory.listFiles()).thenReturn(null); // Simulate empty directory
+        when(mockVersionDirectory.getAbsolutePath()).thenReturn(mockEdgeDirectory + "/v1");
+
+        // Simulate getParent() for files (if necessary)
+        when(mockVersionDirectory.getParent()).thenReturn(mockEdgeDirectory + "/v1");
+
+        // Expect RuntimeException to be thrown when there are no files
+        RuntimeException exception = assertThrows(RuntimeException.class, () -> {
+            configTranslator.getEdgeFiles();
+        });
+    }
+
+    @Test
+    void testGetSchemaVersions() {
+        // Act
+        SchemaVersions result = configTranslator.getSchemaVersions();
+
+        // Assert
+        assertNotNull(result);
+        assertEquals(mockSchemaVersions, result, "The returned SchemaVersions should match the mocked version.");
+    }
+
+    @Test
+    void testGetNodeFiles_noFilesFound() {
+        // Mock the schema locations
+        String mockNodeDirectory = "mock/node/directory";
+        when(mockSchemaLocationsBean.getNodeDirectory()).thenReturn(mockNodeDirectory);
+        when(mockSchemaLocationsBean.getNodesInclusionPattern()).thenReturn(List.of(".*\\.json"));
+        when(mockSchemaLocationsBean.getNodesExclusionPattern()).thenReturn(Collections.emptyList());
+        when(mockSchemaVersion.toString()).thenReturn("v1");
+        File mockVersionDirectory = mock(File.class);
+
+        when(mockVersionDirectory.listFiles()).thenReturn(null);
+        when(mockVersionDirectory.getAbsolutePath()).thenReturn(mockNodeDirectory + "/v1"); // Mock the expected path
+
+        RuntimeException exception = assertThrows(RuntimeException.class, () -> {
+            configTranslator.getNodeFiles();
+        });
+    }
+
+    private File mockFile(String fileName) {
+        File file = mock(File.class);
+        when(file.getName()).thenReturn(fileName);
+        return file;
+    }
+}