diff options
author | 2025-03-24 11:44:34 +0530 | |
---|---|---|
committer | 2025-03-25 10:43:15 +0530 | |
commit | 4637095cf6491d85ab9c79505860769b4c8d1309 (patch) | |
tree | f03896d0218e8d1fa83848a53b31b3a2e66ce446 /aai-traversal | |
parent | b1e15b732534f1c933e3ecc444cdbffaf80fcf68 (diff) |
- 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>
Diffstat (limited to 'aai-traversal')
6 files changed, 682 insertions, 41 deletions
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 index 0000000..c865e60 --- /dev/null +++ b/aai-traversal/src/test/java/org/onap/aai/rest/search/GenericQueryProcessorTest.java @@ -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 index 0000000..e61c7f9 --- /dev/null +++ b/aai-traversal/src/test/java/org/onap/aai/rest/search/GremlinServerSingletonTest.java @@ -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 index 0000000..f01b006 --- /dev/null +++ b/aai-traversal/src/test/java/org/onap/aai/rest/search/LocalCQConfigTest.java @@ -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); + } +} diff --git a/aai-traversal/src/test/java/org/onap/aai/rest/search/ModelAndNamedQueryRestProviderTest.java b/aai-traversal/src/test/java/org/onap/aai/rest/search/ModelAndNamedQueryRestProviderTest.java index e88c536..6e5a980 100644 --- a/aai-traversal/src/test/java/org/onap/aai/rest/search/ModelAndNamedQueryRestProviderTest.java +++ b/aai-traversal/src/test/java/org/onap/aai/rest/search/ModelAndNamedQueryRestProviderTest.java @@ -19,30 +19,8 @@ */ 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 index 0000000..e5515d9 --- /dev/null +++ b/aai-traversal/src/test/java/org/onap/aai/rest/search/SchemaServiceCQConfigTest.java @@ -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(); + } +} diff --git a/aai-traversal/src/test/java/org/onap/aai/rest/search/SearchProviderTest.java b/aai-traversal/src/test/java/org/onap/aai/rest/search/SearchProviderTest.java index 16e3dfe..21aa3ee 100644 --- a/aai-traversal/src/test/java/org/onap/aai/rest/search/SearchProviderTest.java +++ b/aai-traversal/src/test/java/org/onap/aai/rest/search/SearchProviderTest.java @@ -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 |