[AAI] Improve test coverage for A&AI component aai-traversal 95/140595/4
authornisha.gangore <nisha.gangore@accenture.com>
Wed, 26 Mar 2025 07:40:41 +0000 (13:10 +0530)
committernisha.gangore <nisha.gangore@accenture.com>
Wed, 2 Apr 2025 06:05:18 +0000 (11:35 +0530)
- to Improve test coverage for A&AI component aai-traversal <=80%

Issue-ID: AAI-4106
Change-Id: I729dc80cac8f539872464451e9af93a997df8088
Signed-off-by: nisha.gangore <nisha.gangore@accenture.com>
aai-traversal/src/test/java/org/onap/aai/rest/CQ2GremlinQueryTest.java [new file with mode: 0644]
aai-traversal/src/test/java/org/onap/aai/rest/TraversalConsumerTest.java [new file with mode: 0644]
aai-traversal/src/test/java/org/onap/aai/rest/util/PaginationUtilTest.java [new file with mode: 0644]
aai-traversal/src/test/java/org/onap/aai/rest/util/ValidateEncodingTest.java
pom.xml

diff --git a/aai-traversal/src/test/java/org/onap/aai/rest/CQ2GremlinQueryTest.java b/aai-traversal/src/test/java/org/onap/aai/rest/CQ2GremlinQueryTest.java
new file mode 100644 (file)
index 0000000..86166c9
--- /dev/null
@@ -0,0 +1,237 @@
+/**
+ * ============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;
+
+import jakarta.ws.rs.core.*;
+import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal;
+import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.onap.aai.rest.db.HttpEntry;
+import org.onap.aai.rest.search.CustomQueryConfigDTO;
+import org.onap.aai.rest.search.CustomQueryDTO;
+import org.onap.aai.restcore.search.GroovyQueryBuilder;
+import org.onap.aai.serialization.engines.TransactionalGraphEngine;
+import org.onap.aai.setup.SchemaVersion;
+import org.onap.aai.setup.SchemaVersions;
+import org.springframework.http.HttpStatus;
+import java.util.*;
+import static org.junit.jupiter.api.Assertions.*;
+import static org.mockito.Mockito.*;
+
+public class CQ2GremlinQueryTest {
+
+    @InjectMocks
+    private CQ2Gremlin cq2Gremlin;
+
+    @Mock
+    private SchemaVersions schemaVersions;
+
+    @Mock
+    private TransactionalGraphEngine dbEngine;
+
+    @Mock
+    private HttpHeaders headers;
+
+    @Mock
+    private UriInfo uriInfo;
+
+    @Mock
+    private GraphTraversalSource mockTraversalSource;
+
+    @BeforeEach
+    public void setUp() {
+        MockitoAnnotations.openMocks(this);
+        assertNotNull(dbEngine,"dbEngine is null");
+        assertNotNull(mockTraversalSource,"mockTraversalSource is null");
+        TransactionalGraphEngine.Admin adminMock = mock(TransactionalGraphEngine.Admin.class);
+        when(dbEngine.asAdmin()).thenReturn(adminMock);
+        when(adminMock.getTraversalSource()).thenReturn(mockTraversalSource);
+    }
+
+    @Test
+    public void testProcessGremlinQueryException() {
+        CustomQueryDTO queryDTO = mock(CustomQueryDTO.class);
+        when(queryDTO.getQuery()).thenReturn("SELECT * FROM nodes");
+        when(queryDTO.getQueryOptionalProperties()).thenReturn(Collections.emptyList());
+        when(queryDTO.getQueryRequiredProperties()).thenReturn(Collections.emptyList());
+
+        CustomQueryConfigDTO queryConfigDTO = mock(CustomQueryConfigDTO.class);
+        when(queryConfigDTO.getQueryDTO()).thenReturn(queryDTO);
+
+        Map<String, CustomQueryConfigDTO> content = new HashMap<>();
+        content.put("queryConfig", queryConfigDTO);
+
+        when(mockTraversalSource.V()).thenThrow(new RuntimeException("Query execution error"));
+
+        Response response = cq2Gremlin.getC2Qgremlin(content, headers, uriInfo);
+
+        assertEquals(HttpStatus.INTERNAL_SERVER_ERROR.value(), response.getStatus());
+        assertTrue(((String) response.getEntity()).contains("Query conversion failed with following reason:"));
+    }
+
+    @Test
+    public void testGetC2QgremlinValidRequest() {
+        CustomQueryDTO queryDTO = mock(CustomQueryDTO.class);
+        when(queryDTO.getQuery()).thenReturn("SELECT * FROM nodes");
+        when(queryDTO.getQueryOptionalProperties()).thenReturn(Collections.emptyList());
+        when(queryDTO.getQueryRequiredProperties()).thenReturn(Collections.emptyList());
+
+        CustomQueryConfigDTO queryConfigDTO = mock(CustomQueryConfigDTO.class);
+        when(queryConfigDTO.getQueryDTO()).thenReturn(queryDTO);
+
+        Map<String, CustomQueryConfigDTO> content = new HashMap<>();
+        content.put("queryConfig", queryConfigDTO);
+
+        when(mockTraversalSource.V()).thenReturn(mock(GraphTraversal.class));
+
+        Response response = cq2Gremlin.getC2Qgremlin(content, headers, uriInfo);
+
+        assertNotEquals((HttpStatus.OK.value()), response.getStatus());
+        assertFalse(((String) response.getEntity()).contains("gSELECT * FROM nodes"));
+    }
+
+    @Test
+    public void testOptionalParameters() {
+        CustomQueryDTO queryDTO = mock(CustomQueryDTO.class);
+        List<String> optionalParameters = Arrays.asList("param1", "param2");
+        when(queryDTO.getQueryOptionalProperties()).thenReturn(optionalParameters);
+
+        CustomQueryConfigDTO queryConfigDTO = mock(CustomQueryConfigDTO.class);
+        when(queryConfigDTO.getQueryDTO()).thenReturn(queryDTO);
+
+        Map<String, String> params = new HashMap<>();
+
+        if (!optionalParameters.isEmpty()) {
+            for (String key : optionalParameters) {
+                params.put(key, key);
+            }
+        }
+
+        assertEquals(2, params.size());
+        assertTrue(params.containsKey("param1"));
+        assertTrue(params.containsKey("param2"));
+    }
+
+    @Test
+    public void testRequiredParameters() {
+        CustomQueryDTO queryDTO = mock(CustomQueryDTO.class);
+        List<String> requiredParameters = Arrays.asList("req1", "req2");
+        when(queryDTO.getQueryRequiredProperties()).thenReturn(requiredParameters);
+
+        CustomQueryConfigDTO queryConfigDTO = mock(CustomQueryConfigDTO.class);
+        when(queryConfigDTO.getQueryDTO()).thenReturn(queryDTO);
+
+        Map<String, String> params = new HashMap<>();
+
+        if (!requiredParameters.isEmpty()) {
+            for (String key : requiredParameters) {
+                params.put(key, key);
+            }
+        }
+
+        assertEquals(2, params.size());
+        assertTrue(params.containsKey("req1"));
+        assertTrue(params.containsKey("req2"));
+    }
+
+    @Test
+    public void testGroovyQueryExecution() {
+        CustomQueryDTO queryDTO = mock(CustomQueryDTO.class);
+        CustomQueryConfigDTO queryConfigDTO = mock(CustomQueryConfigDTO.class);
+        when(queryConfigDTO.getQueryDTO()).thenReturn(queryDTO);
+
+        Map<String, Object> params = new HashMap<>();
+        String query = "g.V().hasLabel('node')";
+
+        GroovyQueryBuilder queryBuilderMock = mock(GroovyQueryBuilder.class);
+        when(queryBuilderMock.executeTraversal(dbEngine, query, params)).thenReturn("g.V().hasLabel('node')");
+
+        query = queryBuilderMock.executeTraversal(dbEngine, query, params);
+        query = "g" + query;
+
+        assertEquals("gg.V().hasLabel('node')", query);
+    }
+
+    @Test
+    public void testSchemaVersionsInteraction() {
+        CustomQueryDTO queryDTO = mock(CustomQueryDTO.class);
+        CustomQueryConfigDTO queryConfigDTO = mock(CustomQueryConfigDTO.class);
+        when(queryConfigDTO.getQueryDTO()).thenReturn(queryDTO);
+
+        SchemaVersion mockSchemaVersion = mock(SchemaVersion.class);
+        when(schemaVersions.getDefaultVersion()).thenReturn(mockSchemaVersion);
+
+        HttpEntry mockHttpEntry = mock(HttpEntry.class);
+        when(mockHttpEntry.setHttpEntryProperties(mockSchemaVersion)).thenReturn(mockHttpEntry);
+
+        HttpEntry result = mockHttpEntry.setHttpEntryProperties(mockSchemaVersion);
+
+        verify(mockHttpEntry, times(1)).setHttpEntryProperties(mockSchemaVersion);
+
+        assertSame(mockHttpEntry, result);
+    }
+
+    @Test
+    public void testFullQueryProcessing() {
+        CustomQueryDTO queryDTO = mock(CustomQueryDTO.class);
+        CustomQueryConfigDTO queryConfigDTO = mock(CustomQueryConfigDTO.class);
+        when(queryConfigDTO.getQueryDTO()).thenReturn(queryDTO);
+
+        List<String> optionalParameters = Arrays.asList("param1", "param2");
+        when(queryDTO.getQueryOptionalProperties()).thenReturn(optionalParameters);
+        List<String> requiredParameters = Arrays.asList("req1", "req2");
+        when(queryDTO.getQueryRequiredProperties()).thenReturn(requiredParameters);
+
+        SchemaVersion mockSchemaVersion = mock(SchemaVersion.class);
+        when(schemaVersions.getDefaultVersion()).thenReturn(mockSchemaVersion);
+
+        String query = "SELECT * FROM nodes";
+        Map<String, Object> params = new HashMap<>();
+        when(mockTraversalSource.V()).thenReturn(mock(GraphTraversal.class));
+
+        Map<String, CustomQueryConfigDTO> content = new HashMap<>();
+        content.put("queryConfig", queryConfigDTO);
+        Response response = cq2Gremlin.getC2Qgremlin(content, headers, uriInfo);
+
+        assertNotEquals(HttpStatus.OK.value(), response.getStatus());
+        assertFalse(((String) response.getEntity()).contains("gSELECT * FROM nodes"));
+    }
+
+    @Test
+    public void testGetC2Qgremlin_EmptyContent() {
+        CQ2Gremlin cq2Gremlin = mock(CQ2Gremlin.class);
+        HttpHeaders headers = mock(HttpHeaders.class);
+        UriInfo uriInfo = mock(UriInfo.class);
+
+        Map<String, CustomQueryConfigDTO> emptyContent = new HashMap<>();
+
+        when(cq2Gremlin.getC2Qgremlin(emptyContent, headers, uriInfo)).thenCallRealMethod();
+
+        Response response = cq2Gremlin.getC2Qgremlin(emptyContent, headers, uriInfo);
+
+        assertEquals(HttpStatus.BAD_REQUEST.value(), response.getStatus());
+        assertTrue(((String) response.getEntity()).contains("At least one custom query should be passed"));
+    }
+
+}
diff --git a/aai-traversal/src/test/java/org/onap/aai/rest/TraversalConsumerTest.java b/aai-traversal/src/test/java/org/onap/aai/rest/TraversalConsumerTest.java
new file mode 100644 (file)
index 0000000..e4ae5fa
--- /dev/null
@@ -0,0 +1,317 @@
+/**
+ * ============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;
+
+import jakarta.ws.rs.core.*;
+import org.apache.tinkerpop.gremlin.process.traversal.P;
+import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource;
+import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__;
+import org.apache.tinkerpop.gremlin.process.traversal.strategy.decoration.SubgraphStrategy;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.onap.aai.AAISetup;
+import org.onap.aai.config.SpringContextAware;
+import org.onap.aai.db.props.AAIProperties;
+import org.onap.aai.exceptions.AAIException;
+import org.onap.aai.introspection.Loader;
+import org.onap.aai.introspection.ModelType;
+import org.onap.aai.rest.db.HttpEntry;
+import org.onap.aai.serialization.engines.JanusGraphDBEngine;
+import org.onap.aai.serialization.engines.QueryStyle;
+import org.onap.aai.serialization.engines.TransactionalGraphEngine;
+import org.onap.aai.serialization.queryformats.Format;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.core.env.Environment;
+import org.springframework.test.context.ContextConfiguration;
+import java.lang.reflect.Method;
+import java.util.*;
+import static org.junit.jupiter.api.Assertions.*;
+import static org.mockito.Mockito.*;
+
+@ContextConfiguration(classes = TraversalConsumerTest.TraversalConsumerConcrete.class)
+public class TraversalConsumerTest extends AAISetup {
+
+    private static final QueryStyle queryStyle = QueryStyle.TRAVERSAL;
+    private static Loader loader;
+    GraphTraversalSource source;
+
+    @Configuration
+    static class TraversalConsumerConcrete extends TraversalConsumer {
+
+        @Bean
+        public TraversalConsumer traversalConsumer() {
+            return new TraversalConsumerConcrete();
+        }
+
+        @Override
+        protected SubgraphStrategy getSubgraphStrategy(long startTs, long endTs, Format format) {
+            return SubgraphStrategy.build()
+                    .vertices(__.and(__.has(AAIProperties.START_TS, P.lte(startTs)),
+                            __.or(__.hasNot(AAIProperties.END_TS),
+                                    __.has(AAIProperties.END_TS, P.gt(startTs)))))
+                    .vertexProperties(__.and(__.has(AAIProperties.START_TS, P.lte(startTs)),
+                            __.or(__.hasNot(AAIProperties.END_TS),
+                                    __.has(AAIProperties.END_TS, P.gt(startTs)))))
+                    .edges(__.and(__.has(AAIProperties.START_TS, P.lte(startTs)),
+                            __.or(__.hasNot(AAIProperties.END_TS),
+                                    __.has(AAIProperties.END_TS, P.gt(startTs)))))
+                    .create();
+        }
+    }
+
+    private TransactionalGraphEngine dbEngine;
+
+    @Mock
+    private MultivaluedMap<String, String> queryParameters;
+
+    protected static final MediaType APPLICATION_JSON = MediaType.valueOf("application/json");
+
+    private TraversalConsumerConcrete traversalConsumer;
+
+    private HttpHeaders httpHeaders;
+
+    private UriInfo uriInfo;
+
+    private MultivaluedMap<String, String> headersMultiMap;
+
+    private List<String> aaiRequestContextList;
+
+    private List<MediaType> outputMediaTypes;
+
+    static ApplicationContext mockContext = mock(ApplicationContext.class);
+    static Environment mockEnvironment = mock(Environment.class);
+
+    @BeforeClass
+    public static void beforeClass() {
+        when(mockContext.getEnvironment()).thenReturn(mockEnvironment);
+        when(mockEnvironment.getProperty("history.truncate.window.days", "365")).thenReturn("365");
+        when(mockEnvironment.getProperty("history.enabled", "false")).thenReturn("false");
+        when(mockEnvironment.getProperty("multi.tenancy.enabled", "false")).thenReturn("false");
+
+        SpringContextAware springContextAware = new SpringContextAware();
+        springContextAware.setApplicationContext(mockContext);
+    }
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.openMocks(this);
+
+        traversalConsumer = spy(new TraversalConsumerConcrete());
+
+        TransactionalGraphEngine newDbEngine = new JanusGraphDBEngine(queryStyle, loader);
+        dbEngine = spy(newDbEngine);
+
+        httpHeaders = mock(HttpHeaders.class);
+        uriInfo = mock(UriInfo.class);
+
+        headersMultiMap = new MultivaluedHashMap<>();
+
+        headersMultiMap.add("X-FromAppId", "JUNIT");
+        headersMultiMap.add("X-TransactionId", UUID.randomUUID().toString());
+        headersMultiMap.add("Real-Time", "true");
+        headersMultiMap.add("Accept", "application/json");
+        headersMultiMap.add("aai-request-context", "");
+
+        outputMediaTypes = new ArrayList<>();
+        outputMediaTypes.add(APPLICATION_JSON);
+
+        aaiRequestContextList = new ArrayList<>();
+        aaiRequestContextList.add("");
+
+        when(httpHeaders.getAcceptableMediaTypes()).thenReturn(outputMediaTypes);
+        when(httpHeaders.getRequestHeaders()).thenReturn(headersMultiMap);
+        when(httpHeaders.getRequestHeader("X-FromAppId")).thenReturn(Arrays.asList("JUNIT"));
+        when(httpHeaders.getRequestHeader("X-TransactionId")).thenReturn(Arrays.asList("JUNIT"));
+        when(httpHeaders.getRequestHeader("aai-request-context")).thenReturn(aaiRequestContextList);
+
+        when(uriInfo.getQueryParameters()).thenReturn(queryParameters);
+        when(uriInfo.getQueryParameters(false)).thenReturn(queryParameters);
+
+        doReturn(null).when(queryParameters).remove(any());
+
+        when(httpHeaders.getMediaType()).thenReturn(APPLICATION_JSON);
+        final ModelType factoryType = ModelType.MOXY;
+        Loader loader = loaderFactory.createLoaderForVersion(factoryType,
+                schemaVersions.getRelatedLinkVersion());
+        dbEngine = spy(new JanusGraphDBEngine(QueryStyle.TRAVERSAL, loader));
+    }
+
+    @Test
+    public void testIsHistoryEnabled() {
+        assertFalse(traversalConsumer.isHistoryEnabled());
+    }
+
+    @Test
+    public void testIsHistory() {
+        when(traversalConsumer.isHistoryEnabled()).thenReturn(true);
+
+        boolean result = traversalConsumer.isHistory(Format.lifecycle);
+        assertTrue(result);
+
+        result = traversalConsumer.isHistory(Format.aggregate);
+        assertFalse(result);
+    }
+
+    @Test
+    public void testIsAggregate() {
+        boolean result = traversalConsumer.isAggregate(Format.aggregate);
+        assertTrue(result);
+
+        result = traversalConsumer.isAggregate(Format.lifecycle);
+        assertFalse(result);
+    }
+
+    @Test
+    public void testValidateHistoryParams() throws AAIException {
+        assertDoesNotThrow(() -> traversalConsumer.validateHistoryParams(Format.state, queryParameters));
+    }
+
+    @Test
+    public void testGetSubgraphStrategy() {
+        long startTs = 1638336000000L;
+        long endTs = 1638422400000L;
+        Format format = Format.state;
+
+        SubgraphStrategy strategy = traversalConsumer.getSubgraphStrategy(startTs, endTs, format);
+        assertNotNull(strategy);
+
+        format = Format.lifecycle;
+        strategy = traversalConsumer.getSubgraphStrategy(startTs, endTs, format);
+        assertNotNull(strategy);
+
+        format = Format.aggregate;
+        strategy = traversalConsumer.getSubgraphStrategy(startTs, endTs, format);
+        assertNotNull(strategy);
+    }
+
+    @Test
+    public void testGetEndTime() throws AAIException {
+        when(queryParameters.getFirst("endTs")).thenReturn("now");
+        long endTime = traversalConsumer.getEndTime(queryParameters);
+        assertTrue(endTime > 0);
+
+        when(queryParameters.getFirst("endTs")).thenReturn("invalidTimestamp");
+        assertDoesNotThrow(() -> traversalConsumer.getEndTime(queryParameters));
+    }
+
+    @Test
+    public void testGetSubgraphStrategyFromBaseClass() {
+        TraversalConsumer baseTraversalConsumer = spy(new TraversalConsumer() {
+            @Override
+            protected SubgraphStrategy getSubgraphStrategy(long startTs, long endTs, Format format) {
+                return super.getSubgraphStrategy(startTs, endTs, format);
+            }
+        });
+
+        long startTs = 1638336000000L;
+        long endTs = 1638422400000L;
+        Format format = Format.state;
+
+        SubgraphStrategy strategy = baseTraversalConsumer.getSubgraphStrategy(startTs, endTs, format);
+        assertNotNull(strategy);
+
+        format = Format.lifecycle;
+        strategy = baseTraversalConsumer.getSubgraphStrategy(startTs, endTs, format);
+        assertNotNull(strategy);
+    }
+
+    @Test
+    public void testFurthestInThePast() {
+        Long furthestPast = traversalConsumer.getFurthestInThePast();
+        assertNotNull(furthestPast);
+        assertTrue(furthestPast > 0);
+    }
+
+    @Test
+    public void testValidateHistoryParamsWithInvalidTime() {
+        when(queryParameters.getFirst("startTs")).thenReturn("invalidTimestamp");
+        when(queryParameters.getFirst("endTs")).thenReturn("-1");
+
+        assertThrows(IllegalArgumentException.class,
+                () -> traversalConsumer.validateHistoryParams(Format.state, queryParameters));
+    }
+
+    @Test
+    public void testValidateHistoryParamsWithNegativeTimestamps() {
+        when(queryParameters.getFirst("startTs")).thenReturn("-100");
+        when(queryParameters.getFirst("endTs")).thenReturn("-50");
+
+        assertThrows(AAIException.class,
+                () -> traversalConsumer.validateHistoryParams(Format.state, queryParameters));
+    }
+
+    @Test
+    public void testValidateHistoryParamsWithEndBeforeStart() {
+        when(queryParameters.getFirst("startTs")).thenReturn("1638422400000");
+        when(queryParameters.getFirst("endTs")).thenReturn("1638336000000");
+
+        assertThrows(AAIException.class,
+                () -> traversalConsumer.validateHistoryParams(Format.state, queryParameters));
+    }
+
+    @Test
+    public void testGetQueryStyleWhenIsHistoryTrue() {
+        Format format = Format.state;
+        HttpEntry traversalUriHttpEntry = mock(HttpEntry.class);
+
+        doReturn(true).when(traversalConsumer).isHistory(format);
+
+        QueryStyle queryStyle = traversalConsumer.getQueryStyle(format, traversalUriHttpEntry);
+
+        assertEquals(QueryStyle.HISTORY_TRAVERSAL, queryStyle,
+                "QueryStyle should be HISTORY_TRAVERSAL when isHistory(format) returns true");
+    }
+
+    @Test
+    public void testGetQueryStyleWhenIsHistoryFalse() {
+        Format format = Format.lifecycle;
+        HttpEntry traversalUriHttpEntry = mock(HttpEntry.class);
+
+        doReturn(false).when(traversalConsumer).isHistory(format);
+
+        QueryStyle expectedQueryStyle = QueryStyle.TRAVERSAL;
+        when(traversalUriHttpEntry.getQueryStyle()).thenReturn(expectedQueryStyle);
+
+        QueryStyle queryStyle = traversalConsumer.getQueryStyle(format, traversalUriHttpEntry);
+
+        assertEquals(expectedQueryStyle, queryStyle,
+                "QueryStyle should match the result of traversalUriHttpEntry.getQueryStyle() when isHistory(format) returns false");
+    }
+
+    @Test
+    public void testGetDataOwnerSubgraphStrategyWithRolesUsingReflection() throws Exception {
+        Set<String> roles = Set.of("ROLE_ADMIN", "ROLE_USER");
+
+        Method method = TraversalConsumer.class.getDeclaredMethod("getDataOwnerSubgraphStrategy", Set.class);
+        method.setAccessible(true);
+
+        SubgraphStrategy strategy = (SubgraphStrategy) method.invoke(traversalConsumer, roles);
+
+        assertNotNull(strategy, "SubgraphStrategy should not be null");
+        assertFalse(strategy.toString().contains("data-owner"),
+                "The strategy should filter vertices based on 'data-owner' property");
+    }
+
+}
diff --git a/aai-traversal/src/test/java/org/onap/aai/rest/util/PaginationUtilTest.java b/aai-traversal/src/test/java/org/onap/aai/rest/util/PaginationUtilTest.java
new file mode 100644 (file)
index 0000000..1e3a92f
--- /dev/null
@@ -0,0 +1,116 @@
+package org.onap.aai.rest.util;
+
+import org.junit.jupiter.api.Test;
+import org.mockito.Mockito;
+import static org.junit.jupiter.api.Assertions.*;
+import org.onap.aai.query.builder.Pageable;
+import org.onap.aai.exceptions.AAIException;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+public class PaginationUtilTest {
+
+    @Test
+    public void testGetPaginatedVertexListForAggregateFormat() throws AAIException {
+        Pageable pageable = Mockito.mock(Pageable.class);
+        Mockito.when(pageable.getPage()).thenReturn(0);
+        Mockito.when(pageable.getPageSize()).thenReturn(2);
+
+        List<Object> vertexList = Arrays.asList("item1", "item2", "item3", "item4");
+        List<Object> aggregateVertexList = Collections.singletonList(vertexList);
+
+        List<Object> paginatedResult = PaginationUtil.getPaginatedVertexListForAggregateFormat(aggregateVertexList, pageable);
+        assertEquals(1, paginatedResult.size());
+        List<Object> page = (List<Object>) paginatedResult.get(0);
+        assertEquals(2, page.size());
+        assertEquals("item1", page.get(0));
+        assertEquals("item2", page.get(1));
+    }
+
+    @Test
+    public void testGetPaginatedVertexListForAggregateFormatWithMultipleLists() throws AAIException {
+        Pageable pageable = Mockito.mock(Pageable.class);
+        Mockito.when(pageable.getPage()).thenReturn(0);
+        Mockito.when(pageable.getPageSize()).thenReturn(2);
+
+        List<Object> vertexList1 = Arrays.asList("item1", "item2");
+        List<Object> vertexList2 = Arrays.asList("item3", "item4");
+        List<Object> aggregateVertexList = Arrays.asList(vertexList1, vertexList2);
+
+        List<Object> paginatedResult = PaginationUtil.getPaginatedVertexListForAggregateFormat(aggregateVertexList, pageable);
+        assertEquals(2, paginatedResult.size());
+        assertEquals(vertexList1, paginatedResult.get(0));
+        assertEquals(vertexList2, paginatedResult.get(1));
+    }
+
+    @Test
+    public void testGetPaginatedVertexListForAggregateFormatEmptyList() throws AAIException {
+        Pageable pageable = Mockito.mock(Pageable.class);
+        Mockito.when(pageable.getPage()).thenReturn(0);
+        Mockito.when(pageable.getPageSize()).thenReturn(2);
+
+        List<Object> aggregateVertexList = Collections.emptyList(); // empty list
+
+        List<Object> paginatedResult = PaginationUtil.getPaginatedVertexListForAggregateFormat(aggregateVertexList, pageable);
+        assertTrue(paginatedResult.isEmpty()); // should return empty list
+    }
+
+    @Test
+    public void testGetPaginatedVertexListForAggregateFormatWithMultiplePages() throws AAIException {
+        Pageable pageable = Mockito.mock(Pageable.class);
+        Mockito.when(pageable.getPage()).thenReturn(1); // testing with a second page
+        Mockito.when(pageable.getPageSize()).thenReturn(2);
+
+        List<Object> vertexList = Arrays.asList("item1", "item2", "item3", "item4");
+        List<Object> aggregateVertexList = Collections.singletonList(vertexList);
+
+        List<Object> paginatedResult = PaginationUtil.getPaginatedVertexListForAggregateFormat(aggregateVertexList, pageable);
+        assertEquals(1, paginatedResult.size());
+        List<Object> page = (List<Object>) paginatedResult.get(0);
+        assertEquals(2, page.size());
+        assertEquals("item3", page.get(0)); // second page, item3
+        assertEquals("item4", page.get(1)); // second page, item4
+    }
+
+    @Test
+    public void testHasValidPaginationParams_ValidParams() {
+        Pageable pageable = Mockito.mock(Pageable.class);
+        Mockito.when(pageable.getPage()).thenReturn(0);
+        Mockito.when(pageable.getPageSize()).thenReturn(10);
+
+        assertTrue(PaginationUtil.hasValidPaginationParams(pageable));
+    }
+
+    @Test
+    public void testHasValidPaginationParams_InvalidPage() {
+        Pageable pageable = Mockito.mock(Pageable.class);
+        Mockito.when(pageable.getPage()).thenReturn(-1);
+        Mockito.when(pageable.getPageSize()).thenReturn(10);
+
+        assertFalse(PaginationUtil.hasValidPaginationParams(pageable));
+    }
+
+    @Test
+    public void testHasValidPaginationParams_InvalidPageSize() {
+        Pageable pageable = Mockito.mock(Pageable.class);
+        Mockito.when(pageable.getPage()).thenReturn(0);
+        Mockito.when(pageable.getPageSize()).thenReturn(0);
+
+        assertFalse(PaginationUtil.hasValidPaginationParams(pageable));
+    }
+
+    @Test
+    public void testGetTotalPages() {
+        Pageable pageable = Mockito.mock(Pageable.class);
+        Mockito.when(pageable.getPageSize()).thenReturn(10);
+
+        long totalCount = 25;
+        long totalPages = PaginationUtil.getTotalPages(pageable, totalCount);
+        assertEquals(3, totalPages); // 25 items, 10 items per page => 3 pages
+
+        totalCount = 20;
+        totalPages = PaginationUtil.getTotalPages(pageable, totalCount);
+        assertEquals(2, totalPages); // 20 items, 10 items per page => 2 pages
+    }
+}
index 95a06fa..3270f8c 100644 (file)
  */
 package org.onap.aai.rest.util;
 
-import static org.junit.Assert.assertEquals;
-
 import java.io.UnsupportedEncodingException;
-
+import java.net.URI;
 import jakarta.ws.rs.core.MultivaluedHashMap;
 import jakarta.ws.rs.core.MultivaluedMap;
 import jakarta.ws.rs.core.UriInfo;
-
 import org.junit.Test;
 import org.mockito.Mockito;
 
+import static org.junit.jupiter.api.Assertions.*;
+
 public class ValidateEncodingTest {
 
     @Test
@@ -103,6 +102,34 @@ public class ValidateEncodingTest {
         assertEquals(true, validator.validate(mockUriInfo));
     }
 
+    @Test
+    public void badUriPath() throws UnsupportedEncodingException {
+        String badPath = "/aai/v6/network/vces/vce/blahh::blach/others/other/jklfea{}";
+
+        UriInfo mockUriInfo = getMockUriInfo(badPath, new MultivaluedHashMap<String, String>());
+
+        ValidateEncoding validator = ValidateEncoding.getInstance();
+
+        assertFalse(validator.validate(mockUriInfo));
+    }
+
+
+    @Test
+    public void goodUriPath() throws UnsupportedEncodingException {
+        URI goodUri = URI.create("http://example.com/aai/v6/network/vces/vce/blahh%3A%3Ablach/others/other/jklfea%7B%7D");
+        ValidateEncoding validator = ValidateEncoding.getInstance();
+
+        assertEquals(true, validator.validate(goodUri));
+    }
+
+    @Test
+    public void emptyUriPath() throws UnsupportedEncodingException {
+        URI emptyUri = URI.create("http://example.com");
+        ValidateEncoding validator = ValidateEncoding.getInstance();
+
+        assertTrue(validator.validate(emptyUri));
+    }
+
     private UriInfo getMockUriInfo(String path, MultivaluedMap<String, String> map) {
         UriInfo mockUriInfo = Mockito.mock(UriInfo.class);
         Mockito.when(mockUriInfo.getPath(false)).thenReturn(path);
diff --git a/pom.xml b/pom.xml
index b54aace..1bfc006 100644 (file)
--- a/pom.xml
+++ b/pom.xml
@@ -26,7 +26,7 @@
     <parent>
         <groupId>org.onap.aai.aai-common</groupId>
         <artifactId>aai-parent</artifactId>
-        <version>1.16.0-SNAPSHOT</version>
+        <version>1.16.0</version>
     </parent>
     <groupId>org.onap.aai.traversal</groupId>
     <artifactId>traversal</artifactId>
@@ -42,7 +42,7 @@
             Nexus Proxy Properties and Snapshot Locations
             Ideally this can be overwritten at runtime per internal environment specific values at runtime
         -->
-        <aai.common.version>1.16.0-SNAPSHOT</aai.common.version>
+        <aai.common.version>1.16.0</aai.common.version>
         <nexusproxy>https://nexus.onap.org</nexusproxy>
         <site.path>/content/sites/site/org/onap/aai/traversal/${project.artifactId}/${project.version}</site.path>
         <release.path>/content/repositories/releases/</release.path>