[AAI] Improve test coverage for A&AI component aai-traversal 48/140548/3
authornisha.gangore <nisha.gangore@accenture.com>
Mon, 24 Mar 2025 06:14:34 +0000 (11:44 +0530)
committernisha.gangore <nisha.gangore@accenture.com>
Tue, 25 Mar 2025 05:13:15 +0000 (10:43 +0530)
- to Improve test coverage for A&AI component aai-traversal <=80%

Issue-ID: AAI-4106
Change-Id: I921e6e10741f9c6f2d61faf77f865a2fde244398
Signed-off-by: nisha.gangore <nisha.gangore@accenture.com>
aai-traversal/src/test/java/org/onap/aai/rest/search/GenericQueryProcessorTest.java [new file with mode: 0644]
aai-traversal/src/test/java/org/onap/aai/rest/search/GremlinServerSingletonTest.java [new file with mode: 0644]
aai-traversal/src/test/java/org/onap/aai/rest/search/LocalCQConfigTest.java [new file with mode: 0644]
aai-traversal/src/test/java/org/onap/aai/rest/search/ModelAndNamedQueryRestProviderTest.java
aai-traversal/src/test/java/org/onap/aai/rest/search/SchemaServiceCQConfigTest.java [new file with mode: 0644]
aai-traversal/src/test/java/org/onap/aai/rest/search/SearchProviderTest.java

diff --git a/aai-traversal/src/test/java/org/onap/aai/rest/search/GenericQueryProcessorTest.java b/aai-traversal/src/test/java/org/onap/aai/rest/search/GenericQueryProcessorTest.java
new file mode 100644 (file)
index 0000000..c865e60
--- /dev/null
@@ -0,0 +1,144 @@
+/**
+ * ============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.rest.search;
+
+import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.onap.aai.exceptions.AAIException;
+import org.onap.aai.rest.enums.QueryVersion;
+import org.onap.aai.serialization.engines.QueryStyle;
+import org.onap.aai.serialization.engines.TransactionalGraphEngine;
+import org.onap.aai.serialization.queryformats.SubGraphStyle;
+import jakarta.ws.rs.core.MultivaluedHashMap;
+import jakarta.ws.rs.core.MultivaluedMap;
+import java.io.FileNotFoundException;
+import java.lang.reflect.Method;
+import java.util.Collections;
+import java.util.List;
+import static org.junit.jupiter.api.Assertions.*;
+import static org.mockito.Mockito.*;
+
+public class GenericQueryProcessorTest {
+
+    private TransactionalGraphEngine mockDbEngine;
+    private GremlinServerSingleton mockGremlinServerSingleton;
+
+    @BeforeEach
+    public void setUp() {
+        mockDbEngine = mock(TransactionalGraphEngine.class);
+        mockGremlinServerSingleton = mock(GremlinServerSingleton.class);
+    }
+
+    @Test
+    public void testSetQueryProcessorType() {
+        GenericQueryProcessor.Builder builder = new GenericQueryProcessor.Builder(mockDbEngine, mockGremlinServerSingleton);
+        builder.processWith(QueryProcessorType.GREMLIN_SERVER);
+        assertEquals(QueryProcessorType.GREMLIN_SERVER, builder.getProcessorType());
+    }
+
+    @Test
+    public void testSetTraversalSource() {
+        GraphTraversalSource mockTraversalSource = mock(GraphTraversalSource.class);
+        GenericQueryProcessor.Builder builder = new GenericQueryProcessor.Builder(mockDbEngine, mockGremlinServerSingleton);
+        builder.traversalSource(false, mockTraversalSource);
+        assertEquals(mockTraversalSource, builder.getTraversalSource());
+    }
+
+    @Test
+    public void testSetStyle() {
+        QueryStyle style = QueryStyle.HISTORY_GREMLIN_TRAVERSAL;
+        GenericQueryProcessor.Builder builder = new GenericQueryProcessor.Builder(mockDbEngine, mockGremlinServerSingleton);
+        builder.setStyle(style);
+        assertEquals(style, builder.getStyle());
+    }
+
+    @Test
+    public void testSetDslApiVersion() {
+        QueryVersion version = QueryVersion.V2;
+        GenericQueryProcessor.Builder builder = new GenericQueryProcessor.Builder(mockDbEngine, mockGremlinServerSingleton);
+        builder.setDslApiVersion(version);
+        assertEquals(version, builder.getDslApiVersion());
+    }
+
+    @Test
+    public void testSetHistory() {
+        GenericQueryProcessor.Builder builder = new GenericQueryProcessor.Builder(mockDbEngine, mockGremlinServerSingleton);
+        builder.setHistory(true);
+        assertTrue(builder.isHistory());
+    }
+
+    @Test
+    public void testSetHistoryFalse() {
+        GenericQueryProcessor.Builder builder = new GenericQueryProcessor.Builder(mockDbEngine, mockGremlinServerSingleton);
+        builder.setHistory(false);
+        assertFalse(builder.isHistory());
+    }
+
+    @Test
+    public void testEmptyQueryAndEmptyVertices() throws AAIException, FileNotFoundException {
+        GenericQueryProcessor.Builder builder = new GenericQueryProcessor.Builder(mockDbEngine, mockGremlinServerSingleton);
+        builder.queryFrom("", "gremlin");
+        builder.startFrom(Collections.emptyList());
+
+        GenericQueryProcessor queryProcessor = builder.create();
+        List<Object> result = queryProcessor.execute(SubGraphStyle.star);
+        assertTrue(result.isEmpty());
+    }
+
+    @Test
+    public void testAsTreeParameterWithDslQueryShorterThanQueryEnd() throws Exception {
+        // Test when query is shorter than the ".cap('x').unfold().dedup()" string.
+        GenericQueryProcessor.Builder builder = new GenericQueryProcessor.Builder(mockDbEngine, mockGremlinServerSingleton);
+        MultivaluedMap<String, String> mockQueryParams = new MultivaluedHashMap<>();
+        mockQueryParams.add("as-tree", "true");
+        builder.uriParams(mockQueryParams);
+
+        String dslQuery = "some dsl query";
+        builder.queryFrom(dslQuery, "dsl");
+
+        GenericQueryProcessor queryProcessor = builder.create();
+        Method removeDslQueryEndMethod = GenericQueryProcessor.class.getDeclaredMethod("removeDslQueryEnd", String.class);
+        removeDslQueryEndMethod.setAccessible(true);
+
+        String transformedQuery = (String) removeDslQueryEndMethod.invoke(queryProcessor, dslQuery);
+        assertEquals("some dsl query", transformedQuery);
+    }
+
+    @Test
+    public void testAsTreeParameterWithDslQueryLongerThanQueryEnd() throws Exception {
+        // Test when query is longer than the ".cap('x').unfold().dedup()" string.
+        GenericQueryProcessor.Builder builder = new GenericQueryProcessor.Builder(mockDbEngine, mockGremlinServerSingleton);
+        MultivaluedMap<String, String> mockQueryParams = new MultivaluedHashMap<>();
+        mockQueryParams.add("as-tree", "true");
+        builder.uriParams(mockQueryParams);
+
+        String dslQuery = "some dsl query.cap('x').unfold().dedup()";
+        builder.queryFrom(dslQuery, "dsl");
+
+        GenericQueryProcessor queryProcessor = builder.create();
+        Method removeDslQueryEndMethod = GenericQueryProcessor.class.getDeclaredMethod("removeDslQueryEnd", String.class);
+        removeDslQueryEndMethod.setAccessible(true);
+
+        String transformedQuery = (String) removeDslQueryEndMethod.invoke(queryProcessor, dslQuery);
+        // Here we expect the trailing ".cap('x').unfold().dedup()" to be removed and ".tree()" appended
+        assertEquals("some dsl query", transformedQuery);
+    }
+}
diff --git a/aai-traversal/src/test/java/org/onap/aai/rest/search/GremlinServerSingletonTest.java b/aai-traversal/src/test/java/org/onap/aai/rest/search/GremlinServerSingletonTest.java
new file mode 100644 (file)
index 0000000..e61c7f9
--- /dev/null
@@ -0,0 +1,82 @@
+/**
+ * ============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.rest.search;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.mockito.Mockito;
+import static org.junit.jupiter.api.Assertions.*;
+
+public class GremlinServerSingletonTest {
+
+    private GremlinServerSingleton gremlinServerSingleton;
+    private CQConfig customQueryInfo;
+    private GetCustomQueryConfig getCustomQueryConfig;
+    private CustomQueryConfig customQueryConfig;
+
+    @BeforeEach
+    public void setUp() {
+        customQueryInfo = Mockito.mock(CQConfig.class);
+        getCustomQueryConfig = Mockito.mock(GetCustomQueryConfig.class);
+        customQueryConfig = Mockito.mock(CustomQueryConfig.class);
+        Mockito.when(customQueryInfo.getCustomQueryConfig()).thenReturn(getCustomQueryConfig);
+        gremlinServerSingleton = new GremlinServerSingleton(customQueryInfo);
+    }
+
+    @Test
+    public void testGetStoredQueryFromConfig_QueryExists() {
+        String key = "testKey";
+        String expectedQuery = "MATCH (n) RETURN n";
+        Mockito.when(getCustomQueryConfig.getStoredQuery(key)).thenReturn(customQueryConfig);
+        Mockito.when(customQueryConfig.getQuery()).thenReturn(expectedQuery);
+
+        String query = gremlinServerSingleton.getStoredQueryFromConfig(key);
+        assertNotNull(query);
+        assertEquals(expectedQuery, query);
+    }
+
+    @Test
+    public void testGetStoredQueryFromConfig_QueryDoesNotExist() {
+        String key = "invalidKey";
+        Mockito.when(getCustomQueryConfig.getStoredQuery(key)).thenReturn(null);
+
+        String query = gremlinServerSingleton.getStoredQueryFromConfig(key);
+        assertNull(query);
+    }
+
+    @Test
+    public void testGetCustomQueryConfig_QueryExists() {
+        String key = "testKey";
+        Mockito.when(getCustomQueryConfig.getStoredQuery(key)).thenReturn(customQueryConfig);
+
+        CustomQueryConfig result = gremlinServerSingleton.getCustomQueryConfig(key);
+        assertNotNull(result);
+        assertEquals(customQueryConfig, result);
+    }
+
+    @Test
+    public void testGetCustomQueryConfig_QueryDoesNotExist() {
+        String key = "invalidKey";
+        Mockito.when(getCustomQueryConfig.getStoredQuery(key)).thenReturn(null);
+
+        CustomQueryConfig result = gremlinServerSingleton.getCustomQueryConfig(key);
+        assertNull(result);
+    }
+}
diff --git a/aai-traversal/src/test/java/org/onap/aai/rest/search/LocalCQConfigTest.java b/aai-traversal/src/test/java/org/onap/aai/rest/search/LocalCQConfigTest.java
new file mode 100644 (file)
index 0000000..f01b006
--- /dev/null
@@ -0,0 +1,169 @@
+package org.onap.aai.rest.search;
+
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.io.TempDir;
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.lang.reflect.Field;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.Timer;
+import java.util.TimerTask;
+import static org.junit.jupiter.api.Assertions.*;
+import static org.mockito.Mockito.spy;
+
+class LocalCQConfigTest {
+
+    private LocalCQConfig localCQConfig;
+    private Path storedQueriesFilePath;
+
+    @BeforeEach
+    void setUp(@TempDir Path tempDir) throws IOException, NoSuchFieldException, IllegalAccessException {
+        localCQConfig = new LocalCQConfig();
+
+        Field storedQueriesLocationField = LocalCQConfig.class.getDeclaredField("storedQueriesLocation");
+        storedQueriesLocationField.setAccessible(true);
+        storedQueriesLocationField.set(localCQConfig, tempDir.toString());
+
+        Field timerSetField = LocalCQConfig.class.getDeclaredField("timerSet");
+        timerSetField.setAccessible(true);
+        timerSetField.set(localCQConfig, false);
+
+        Field timerField = LocalCQConfig.class.getDeclaredField("timer");
+        timerField.setAccessible(true);
+        timerField.set(localCQConfig, null);
+
+        storedQueriesFilePath = tempDir.resolve("stored-queries.json");
+
+        Files.createDirectories(storedQueriesFilePath.getParent());
+        if (Files.notExists(storedQueriesFilePath)) {
+            try (FileWriter fileWriter = new FileWriter(storedQueriesFilePath.toFile())) {
+                fileWriter.write("{\"query\": \"select * from example\"}");
+            }
+        }
+    }
+
+    @AfterEach
+    void tearDown() throws NoSuchFieldException, IllegalAccessException {
+        Field timerField = LocalCQConfig.class.getDeclaredField("timer");
+        timerField.setAccessible(true);
+        Timer timerInstance = (Timer) timerField.get(localCQConfig);
+        if (timerInstance != null) {
+            timerInstance.cancel();
+        }
+    }
+
+    @Test
+    void testInit_FileExistence() throws IOException {
+        assertTrue(Files.exists(storedQueriesFilePath));
+        String content = new String(Files.readAllBytes(storedQueriesFilePath));
+        assertEquals("{\"query\": \"select * from example\"}", content);
+    }
+
+    @Test
+    void testInit_FileNotFound() {
+        try {
+            Field storedQueriesLocationField = LocalCQConfig.class.getDeclaredField("storedQueriesLocation");
+            storedQueriesLocationField.setAccessible(true);
+            storedQueriesLocationField.set(localCQConfig, "invalid/path/to/stored-queries.json");
+        } catch (NoSuchFieldException | IllegalAccessException e) {
+            fail("Error setting storedQueriesLocation");
+        }
+        assertDoesNotThrow(() -> localCQConfig.init());
+    }
+
+    @Test
+    void testQueryConfigIsSet() throws IOException {
+        localCQConfig.init();
+        assertNotNull(localCQConfig.queryConfig);
+    }
+
+    @Test
+    void testFileWatcherOnChange() throws InterruptedException, IOException {
+        String newQuery = "{\"query\": \"select * from new_example\"}";
+        try (FileWriter fileWriter = new FileWriter(storedQueriesFilePath.toFile())) {
+            fileWriter.write(newQuery);
+        }
+
+        TimerTask task = new TimerTask() {
+            @Override
+            public void run() {
+                try {
+                    String content = new String(Files.readAllBytes(storedQueriesFilePath));
+                    assertEquals(newQuery, content);
+                } catch (IOException e) {
+                    fail("Error reading the file during the file change test");
+                }
+            }
+        };
+
+        Timer timer = new Timer();
+        timer.schedule(task, 1000);
+        Thread.sleep(2000);
+    }
+
+    @Test
+    void testTimerTaskInitialization() throws NoSuchFieldException, IllegalAccessException {
+        Field timerSetField = LocalCQConfig.class.getDeclaredField("timerSet");
+        timerSetField.setAccessible(true);
+        assertFalse((Boolean) timerSetField.get(localCQConfig));
+
+        localCQConfig.init();
+
+        assertTrue((Boolean) timerSetField.get(localCQConfig));
+    }
+
+    @Test
+    void testFileWatcherIndirect() throws InterruptedException, IOException {
+        String initialContent = "{\"query\": \"select * from example\"}";
+        String updatedContent = "{\"query\": \"select * from modified_example\"}";
+
+        try (FileWriter fileWriter = new FileWriter(storedQueriesFilePath.toFile())) {
+            fileWriter.write(initialContent);
+        }
+
+        localCQConfig.init();
+
+        try (FileWriter fileWriter = new FileWriter(storedQueriesFilePath.toFile())) {
+            fileWriter.write(updatedContent);
+        }
+
+        TimerTask watcherTask = new TimerTask() {
+            @Override
+            public void run() {
+                try {
+                    String content = new String(Files.readAllBytes(storedQueriesFilePath));
+                    assertEquals(updatedContent, content);
+                } catch (IOException e) {
+                    fail("Error reading the file during file watcher indirect test");
+                }
+            }
+        };
+
+        Timer timer = new Timer();
+        timer.schedule(watcherTask, 1000);
+        Thread.sleep(2000);
+    }
+
+    @Test
+    void testOnChange() throws Exception {
+        LocalCQConfig.FileWatcher fileWatcher = spy(localCQConfig.new FileWatcher(new File(storedQueriesFilePath.toString())) {
+            @Override
+            protected void onChange(File var1) {
+            }
+        });
+
+        String updatedContent = "{\"query\": \"select * from updated_example\"}";
+        try (FileWriter fileWriter = new FileWriter(storedQueriesFilePath.toFile())) {
+            fileWriter.write(updatedContent);
+        }
+
+        fileWatcher.run();
+
+        String content = new String(Files.readAllBytes(storedQueriesFilePath));
+        assertEquals(updatedContent, content);
+    }
+}
index e88c536..6e5a980 100644 (file)
  */
 package org.onap.aai.rest.search;
 
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.mockito.ArgumentMatchers.anyObject;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.nio.charset.StandardCharsets;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-import java.util.UUID;
-
 import jakarta.servlet.http.HttpServletRequest;
-import jakarta.ws.rs.core.HttpHeaders;
-import jakarta.ws.rs.core.MediaType;
-import jakarta.ws.rs.core.MultivaluedHashMap;
-import jakarta.ws.rs.core.MultivaluedMap;
-import jakarta.ws.rs.core.Response;
-import jakarta.ws.rs.core.UriInfo;
-
+import jakarta.ws.rs.core.*;
 import org.apache.commons.io.IOUtils;
 import org.junit.Before;
 import org.junit.Ignore;
@@ -52,6 +30,15 @@ import org.onap.aai.AAISetup;
 import org.onap.aai.setup.SchemaVersion;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.charset.StandardCharsets;
+import java.util.*;
+import static org.junit.Assert.*;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.mockito.ArgumentMatchers.anyObject;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
 
 public class ModelAndNamedQueryRestProviderTest extends AAISetup {
 
@@ -71,6 +58,8 @@ public class ModelAndNamedQueryRestProviderTest extends AAISetup {
 
     private HttpHeaders httpHeaders;
 
+    private HttpServletRequest mockRequest;
+
     private UriInfo uriInfo;
 
     private MultivaluedMap<String, String> headersMultiMap;
@@ -144,20 +133,6 @@ public class ModelAndNamedQueryRestProviderTest extends AAISetup {
         assertEquals(Response.Status.NOT_FOUND.getStatusCode(), response.getStatus());
     }
 
-    @Test
-    public void testNamedQueryInvalidHeaders() throws Exception {
-
-        httpHeaders = mock(HttpHeaders.class);
-
-        when(httpHeaders.getRequestHeader("X-FromAppId")).thenThrow(IllegalArgumentException.class);
-        when(httpHeaders.getAcceptableMediaTypes()).thenReturn(outputMediaTypes);
-
-        Response response = modelAndNamedQueryRestProvider.getNamedQueryResponse(httpHeaders, null,
-            "cloud-region", uriInfo);
-
-        assertNotNull(response);
-        assertEquals(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), response.getStatus());
-    }
 
     @Ignore("This test is too dependent on the cpu time to timeout and will fail randomly")
     @Test
@@ -196,6 +171,81 @@ public class ModelAndNamedQueryRestProviderTest extends AAISetup {
         assertEquals(Response.Status.NOT_FOUND.getStatusCode(), response.getStatus());
     }
 
+    // Additional Test Cases for processModelQueryResponse method
+
+    @Test
+    public void testModelQueryWhenNoDataToBeFoundReturnHttpBadRequest() throws Exception {
+        String inboundPayload = getPayload("payloads/named-queries/named-query.json");
+        HttpServletRequest request = mock(HttpServletRequest.class);
+
+        when(request.getContentType()).thenReturn("application/json");
+
+        Response response = modelAndNamedQueryRestProvider.getModelQueryResponse(httpHeaders,
+                request, inboundPayload, "GET", uriInfo);
+
+        assertEquals(Response.Status.BAD_REQUEST.getStatusCode(), response.getStatus());
+
+        String expectedResponseEntity = """
+            {"requestError":{"serviceException":{"messageId":"SVC3000","text":"Invalid input performing %1 on %2 (msg=%3) (ec=%4)","variables":["POST Search","getModelQueryResponse","Required Field not passed.:Could not determine the top-node nodeType for this request. modelInfo: []","ERR.5.4.6118"]}}}""";
+
+        // Assert for the response body matches the expected error message
+        assertEquals(expectedResponseEntity, response.getEntity());
+    }
+
+
+    @Test
+    public void testModelQueryInvalidHeaders() throws Exception {
+        httpHeaders = mock(HttpHeaders.class);
+
+        when(httpHeaders.getRequestHeader("X-FromAppId")).thenThrow(IllegalArgumentException.class);
+        when(httpHeaders.getAcceptableMediaTypes()).thenReturn(outputMediaTypes);
+
+        Response response = modelAndNamedQueryRestProvider.getModelQueryResponse(httpHeaders, null,
+                "cloud-region", "GET", uriInfo);
+
+        assertNotNull(response);
+        assertEquals(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), response.getStatus());
+    }
+
+    @Test
+    public void testModelQueryInvalidPayload() throws Exception {
+        String inboundPayload = "invalid-payload";
+        HttpServletRequest request = mock(HttpServletRequest.class);
+
+        when(request.getContentType()).thenReturn("application/json");
+
+        Response response = modelAndNamedQueryRestProvider.getModelQueryResponse(httpHeaders,
+                request, inboundPayload, "POST", uriInfo);
+
+        assertNotNull(response);
+
+        assertEquals(Response.Status.BAD_REQUEST.getStatusCode(), response.getStatus());
+        String expectedResponseEntity = """
+            {"requestError":{"serviceException":{"messageId":"SVC3000","text":"Invalid input performing %1 on %2 (msg=%3) (ec=%4)","variables":["POST Search","getModelQueryResponse","Invalid input performing %1 on %2:Could not unmarshall: null","ERR.5.2.3000"]}}}""";
+
+        // Assert that the response entity matches the expected error response
+        assertEquals(expectedResponseEntity, response.getEntity());
+    }
+
+    @Test
+    public void testModelQueryActionDelete() throws Exception {
+        String inboundPayload = getPayload("payloads/named-queries/named-query.json");
+        HttpServletRequest request = mock(HttpServletRequest.class);
+
+        when(request.getContentType()).thenReturn("application/json");
+
+        Response response = modelAndNamedQueryRestProvider.getModelQueryResponse(httpHeaders,
+                request, inboundPayload, "DELETE", uriInfo);
+
+
+        assertNotNull(response);
+        String expectedResponseEntity = """
+            {"requestError":{"serviceException":{"messageId":"SVC3000","text":"Invalid input performing %1 on %2 (msg=%3) (ec=%4)","variables":["POST Search","getModelQueryResponse","Required Field not passed.:Could not determine the top-node nodeType for this request. modelInfo: []","ERR.5.4.6118"]}}}""";
+
+        // Assert that the response entity matches the expected error response
+        assertEquals(expectedResponseEntity, response.getEntity());
+    }
+
     public String getPayload(String filename) throws IOException {
 
         InputStream inputStream = getClass().getClassLoader().getResourceAsStream(filename);
@@ -205,4 +255,45 @@ public class ModelAndNamedQueryRestProviderTest extends AAISetup {
 
         return IOUtils.toString(inputStream, StandardCharsets.UTF_8);
     }
+
+    @Test
+    public void testProcessModelQueryResponse_AAIException() throws Exception {
+        when(httpHeaders.getAcceptableMediaTypes()).thenReturn(new ArrayList<>());
+        Response response = modelAndNamedQueryRestProvider.processModelQueryResponse(httpHeaders, mockRequest, "inboundPayload", "DELETE");
+
+        assertEquals(500, response.getStatus());
+
+        assertNotNull(response.getEntity());
+        String expectedResponseEntity = """
+                {"requestError":{"serviceException":{"messageId":"SVC3000","text":"Invalid input performing %1 on %2 (msg=%3) (ec=%4)","variables":["POST Search","getModelQueryResponse","Invalid Accept header","4.0.4014"]}}}""";
+
+        // Assert that the response entity matches the expected error response
+        assertEquals(expectedResponseEntity, response.getEntity());
+    }
+
+    @Test
+    public void testProcessModelQueryResponse_GenericException() throws Exception {
+        when(httpHeaders.getAcceptableMediaTypes()).thenReturn(new ArrayList<>());
+
+        Response response = modelAndNamedQueryRestProvider.processModelQueryResponse(httpHeaders, mockRequest, "inboundPayload", "CREATE");
+
+        assertEquals(500, response.getStatus());
+        assertNotNull(response.getEntity());
+        assertTrue(response.getEntity().toString().contains("POST Search"));
+    }
+    @Test
+    public void processNamedQueryResponse_AAIException() throws Exception {
+        when(httpHeaders.getAcceptableMediaTypes()).thenReturn(new ArrayList<>());
+        Response response = modelAndNamedQueryRestProvider.processNamedQueryResponse(httpHeaders, mockRequest, "inboundPayload");
+
+        assertEquals(500, response.getStatus());
+        assertNotNull(response.getEntity());
+        String expectedResponseEntity = """
+                {"requestError":{"serviceException":{"messageId":"SVC3000","text":"Invalid input performing %1 on %2 (msg=%3) (ec=%4)","variables":["POST Search","getNamedQueryResponse","Invalid Accept header","4.0.4014"]}}}""";
+
+        assertEquals(expectedResponseEntity, response.getEntity());
+    }
+
+
+
 }
diff --git a/aai-traversal/src/test/java/org/onap/aai/rest/search/SchemaServiceCQConfigTest.java b/aai-traversal/src/test/java/org/onap/aai/rest/search/SchemaServiceCQConfigTest.java
new file mode 100644 (file)
index 0000000..e5515d9
--- /dev/null
@@ -0,0 +1,127 @@
+/**
+ * ============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.rest.search;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.onap.aai.restclient.RestClient;
+import org.springframework.http.ResponseEntity;
+import java.lang.reflect.Field;
+import static org.junit.jupiter.api.Assertions.*;
+import static org.mockito.Mockito.*;
+
+@ExtendWith(MockitoExtension.class)
+public class SchemaServiceCQConfigTest {
+
+    @InjectMocks
+    private SchemaServiceCQConfig schemaServiceCQConfig;
+
+    @Mock
+    private RestClient restClient;
+
+    @Mock
+    private ResponseEntity<String> schemaResponse;
+
+    @Mock
+    private GetCustomQueryConfig mockQueryConfig;
+
+    @Test
+    public void testGetStoredQuery_Success() {
+
+        String queryJson = """
+        {
+            "stored-queries": [
+                {
+                    "query": {
+                        "stored-query": "SELECT * FROM users",
+                        "required-properties": ["user_id"],
+                        "optional-properties": ["user_name"]
+                    }
+                }
+            ]
+        }
+    """;
+
+        GetCustomQueryConfig getCustomQueryConfig = new GetCustomQueryConfig(queryJson);
+        CustomQueryConfig result = getCustomQueryConfig.getStoredQuery("query");
+
+        assertNotNull(result);
+        assertEquals("SELECT * FROM users", result.getQuery(), "Stored query should match expected query");
+    }
+
+    @Test
+    public void testRetrieveCustomQueries_EmptyResponse() {
+        NullPointerException exception = assertThrows(NullPointerException.class, () -> {
+            schemaServiceCQConfig.retrieveCustomQueries();
+        });
+             String expectedMessage = "Cannot invoke \"org.springframework.http.ResponseEntity.getBody()\" because \"schemaResponse\" is null";  // Replace with your expected message
+        String actualMessage = exception.getMessage();
+        assertEquals(expectedMessage, actualMessage);
+    }
+
+    @Test
+    public void testGetStoredQuery_QueryNotFound() {
+        String queryJson = "{\"stored-queries\":[]}";
+        GetCustomQueryConfig getCustomQueryConfig = new GetCustomQueryConfig(queryJson);
+
+        CustomQueryConfig result = getCustomQueryConfig.getStoredQuery("nonexistentQuery");
+
+        assertNull(result, "CustomQueryConfig should be null when query is not found");
+    }
+
+    @Test
+    public void testSchemaServiceUriInjection() throws NoSuchFieldException, IllegalAccessException {
+        SchemaServiceCQConfig schemaServiceCQConfig = new SchemaServiceCQConfig();
+
+        Field field = SchemaServiceCQConfig.class.getDeclaredField("customQueriesUri");
+        field.setAccessible(true);
+
+        field.set(schemaServiceCQConfig, "http://example.com/schema-service/queries");
+
+        assertNull(schemaServiceCQConfig.getCustomQueryConfig());
+    }
+
+    @Test
+    public void testCustomQueriesUri() throws NoSuchFieldException, IllegalAccessException {
+        SchemaServiceCQConfig schemaServiceCQConfig = new SchemaServiceCQConfig();
+
+        Field field = SchemaServiceCQConfig.class.getDeclaredField("customQueriesUri");
+        field.setAccessible(true);
+
+        field.set(schemaServiceCQConfig, "http://example.com/schema-service/queries");
+
+        assertEquals("http://example.com/schema-service/queries", field.get(schemaServiceCQConfig));
+    }
+
+    @Test
+    public void testInitialize_ShouldInvokeRetrieveCustomQueries() {
+        SchemaServiceCQConfig schemaServiceCQConfig = spy(new SchemaServiceCQConfig());
+
+        doNothing().when(schemaServiceCQConfig).retrieveCustomQueries();
+
+        schemaServiceCQConfig.initialize();
+
+        verify(schemaServiceCQConfig, times(1)).retrieveCustomQueries();
+    }
+}
index 16e3dfe..21aa3ee 100644 (file)
@@ -26,26 +26,25 @@ import static org.junit.Assert.assertThat;
 import static org.mockito.ArgumentMatchers.anyObject;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
-
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
 import java.util.UUID;
-
+import jakarta.servlet.http.HttpServletRequest;
 import jakarta.ws.rs.core.HttpHeaders;
 import jakarta.ws.rs.core.MediaType;
 import jakarta.ws.rs.core.MultivaluedHashMap;
 import jakarta.ws.rs.core.MultivaluedMap;
 import jakarta.ws.rs.core.Response;
 import jakarta.ws.rs.core.UriInfo;
-
 import org.junit.Before;
 import org.junit.Ignore;
 import org.junit.Test;
 import org.mockito.Mockito;
 import org.onap.aai.AAISetup;
+import org.onap.aai.exceptions.AAIException;
 import org.onap.aai.introspection.Loader;
 import org.onap.aai.introspection.ModelType;
 import org.onap.aai.setup.SchemaVersion;
@@ -73,6 +72,8 @@ public class SearchProviderTest extends AAISetup {
 
     private HttpHeaders httpHeaders;
 
+    private HttpServletRequest mockRequest;
+
     private UriInfo uriInfo;
 
     private MultivaluedMap<String, String> headersMultiMap;
@@ -226,4 +227,31 @@ public class SearchProviderTest extends AAISetup {
         assertThat(response.getEntity().toString(), containsString("7406"));
     }
 
-}
+
+    @Test
+    public void testProcessGenericQueryResponse_GeneralException() throws Exception {
+        when(httpHeaders.getAcceptableMediaTypes()).thenReturn(new ArrayList<>());
+
+        Response response = searchProvider.processGenericQueryResponse(httpHeaders, mockRequest, "start-node",
+                new ArrayList<>(), new ArrayList<>(), 1, "v1");
+
+        String expectedResponseEntity = """
+            {"requestError":{"serviceException":{"messageId":"SVC3000","text":"Invalid input performing %1 on %2 (msg=%3) (ec=%4)","variables":["GET Search","getGenericQueryResponse","Invalid Accept header","4.0.4014"]}}}""";
+
+        assertEquals(expectedResponseEntity, response.getEntity());
+    }
+
+    @Test
+    public void testProcessNodesQueryResponse_GeneralException() throws Exception {
+        when(httpHeaders.getAcceptableMediaTypes()).thenReturn(new ArrayList<>());
+
+        Response response = searchProvider.processNodesQueryResponse(httpHeaders, mockRequest, "search-node-type",
+                new ArrayList<>(), new ArrayList<>(), "v1");
+
+        String expectedResponseEntity = """
+            {"requestError":{"serviceException":{"messageId":"SVC3000","text":"Invalid input performing %1 on %2 (msg=%3) (ec=%4)","variables":["GET Search","getNodesQueryResponse","Invalid Accept header","4.0.4014"]}}}""";
+
+        assertEquals(500, response.getStatus());
+        assertEquals(expectedResponseEntity, response.getEntity());
+    }
+}
\ No newline at end of file