diff options
Diffstat (limited to 'aai-traversal')
5 files changed, 701 insertions, 34 deletions
diff --git a/aai-traversal/src/test/java/org/onap/aai/dbgraphmap/SearchGraphTest.java b/aai-traversal/src/test/java/org/onap/aai/dbgraphmap/SearchGraphTest.java index 68e30aa..cdafcb5 100644 --- a/aai-traversal/src/test/java/org/onap/aai/dbgraphmap/SearchGraphTest.java +++ b/aai-traversal/src/test/java/org/onap/aai/dbgraphmap/SearchGraphTest.java @@ -19,27 +19,6 @@ */ package org.onap.aai.dbgraphmap; -import static org.mockito.ArgumentMatchers.anyObject; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -import java.net.URI; -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 java.util.stream.Stream; - -import javax.servlet.http.HttpServletRequest; -import javax.ws.rs.core.HttpHeaders; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.MultivaluedHashMap; -import javax.ws.rs.core.MultivaluedMap; -import javax.ws.rs.core.Response; -import javax.ws.rs.core.UriInfo; - import org.apache.tinkerpop.gremlin.structure.Vertex; import org.eclipse.persistence.dynamic.DynamicEntity; import org.janusgraph.graphdb.types.system.EmptyVertex; @@ -62,6 +41,15 @@ import org.onap.aai.serialization.queryformats.utils.UrlBuilder; import org.onap.aai.setup.SchemaVersion; import org.onap.aai.util.GenericQueryBuilder; import org.onap.aai.util.NodesQueryBuilder; +import javax.servlet.http.HttpServletRequest; +import javax.ws.rs.core.*; +import java.net.URI; +import java.util.*; +import java.util.stream.Stream; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.mockito.ArgumentMatchers.anyObject; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; public class SearchGraphTest extends AAISetup { @@ -173,7 +161,9 @@ public class SearchGraphTest extends AAISetup { new GenericQueryBuilder().setHeaders(httpHeaders).setStartNodeType("service-instance") .setStartNodeKeyParams(keys).setIncludeNodeTypes(includeStrings).setDepth(1) .setDbEngine(dbEngine).setLoader(loader).setUrlBuilder(urlBuilder)); - System.out.println(response); + Assert.assertEquals(200,response.getStatus()); + Object entity = response.getEntity(); + Assert.assertNotNull(entity); } @Test(expected = AAIException.class) @@ -225,6 +215,13 @@ public class SearchGraphTest extends AAISetup { .setStartNodeType("").setStartNodeKeyParams(keys).setIncludeNodeTypes(null) .setDepth(1).setDbEngine(dbEngine).setLoader(loader).setUrlBuilder(urlBuilder)); System.out.println(response); + + String responseJson = response.toString(); + + // Assertions + Assert.assertNotNull(responseJson); + Assert.assertTrue(responseJson.contains("result-data")); + Assert.assertTrue(responseJson.contains("cloud-region")); } @Test @@ -244,6 +241,13 @@ public class SearchGraphTest extends AAISetup { Introspector response = searchGraph.createSearchResults(loader, urlBuilder, keys); System.out.println(response); + + String responseJson = response.toString(); + + Assert.assertNotNull(responseJson); + Assert.assertTrue(responseJson.contains("result-data")); + Assert.assertTrue(responseJson.contains("cloud-region")); + } @Test(expected = AAIException.class) @@ -289,6 +293,10 @@ public class SearchGraphTest extends AAISetup { .setEdgeFilterParams(edgeFilter).setFilterParams(filter).setDbEngine(dbEngine) .setLoader(loader).setUrlBuilder(urlBuilder)); Assert.assertNotNull(response); + Assert.assertEquals(200,response.getStatus()); + Assert.assertNotNull(response); + Object entity = response.getEntity(); + Assert.assertNotNull(entity); } @Test @@ -303,6 +311,23 @@ public class SearchGraphTest extends AAISetup { .setEdgeFilterParams(edgeFilter).setFilterParams(filter).setDbEngine(dbEngine) .setLoader(loader).setUrlBuilder(urlBuilder)); Assert.assertNotNull(response); + Object entity = response.getEntity(); + Assert.assertNotNull(entity); + } + + @Test + public void runNodesQueryTargetNodeTypeNullTest() throws AAIException { + UrlBuilder urlBuilder = mock(UrlBuilder.class); + List<String> filter = new ArrayList<String>(); + filter.add("model:EQUALS:DOES-NOT-EXIST:AAI"); + List<String> edgeFilter = new ArrayList<String>(); + edgeFilter.add("model:EXISTS:DOES-NOT-EXIST:AAI"); + + assertThrows(AAIException.class, + () -> searchGraph.runNodesQuery( + new NodesQueryBuilder().setHeaders(httpHeaders).setTargetNodeType(null) + .setEdgeFilterParams(edgeFilter).setFilterParams(filter).setDbEngine(dbEngine) + .setLoader(loader).setUrlBuilder(urlBuilder))); } @Test @@ -311,9 +336,12 @@ public class SearchGraphTest extends AAISetup { List<String> filter = new ArrayList<String>(); filter.add("model:DOES-NOT-EQUAL:DOES-NOT-EXIST"); List<String> edgeFilter = new ArrayList<>(); - searchGraph.runNodesQuery(new NodesQueryBuilder().setHeaders(httpHeaders) - .setTargetNodeType("model-ver").setEdgeFilterParams(edgeFilter).setFilterParams(filter) - .setDbEngine(dbEngine).setLoader(loader).setUrlBuilder(urlBuilder)); + Response response = searchGraph.runNodesQuery(new NodesQueryBuilder().setHeaders(httpHeaders) + .setTargetNodeType("model-ver").setEdgeFilterParams(edgeFilter).setFilterParams(filter) + .setDbEngine(dbEngine).setLoader(loader).setUrlBuilder(urlBuilder)); + Assert.assertNotNull(response); + Object entity = response.getEntity(); + Assert.assertNotNull(entity); } @Test @@ -322,9 +350,29 @@ public class SearchGraphTest extends AAISetup { List<String> filter = new ArrayList<>(); filter.add("model:DOES-NOT-EQUAL:DOES-NOT-EXIST:AAI"); List<String> edgeFilter = new ArrayList<>(); - searchGraph.runNodesQuery(new NodesQueryBuilder().setHeaders(httpHeaders) - .setTargetNodeType("model-ver").setEdgeFilterParams(edgeFilter).setFilterParams(filter) - .setDbEngine(dbEngine).setLoader(loader).setUrlBuilder(urlBuilder)); + Response response = searchGraph.runNodesQuery(new NodesQueryBuilder().setHeaders(httpHeaders) + .setTargetNodeType("model-ver").setEdgeFilterParams(edgeFilter).setFilterParams(filter) + .setDbEngine(dbEngine).setLoader(loader).setUrlBuilder(urlBuilder)); + Assert.assertNotNull(response); + Assert.assertEquals(200,response.getStatus()); + Object entity = response.getEntity(); + Assert.assertNotNull(entity); + + } + + @Test + public void runNodesQueryTestNoFilterParam() throws AAIException { + UrlBuilder urlBuilder = mock(UrlBuilder.class); + List<String> filter = new ArrayList<>(); + //filter.add("model:DOES-NOT-EQUAL:DOES-NOT-EXIST:AAI"); + List<String> edgeFilter = new ArrayList<>(); + Response response = searchGraph.runNodesQuery(new NodesQueryBuilder().setHeaders(httpHeaders) + .setTargetNodeType("model-ver").setEdgeFilterParams(edgeFilter).setFilterParams(filter) + .setDbEngine(dbEngine).setLoader(loader).setUrlBuilder(urlBuilder)); + Assert.assertNotNull(response); + Assert.assertEquals(200,response.getStatus()); + Object entity = response.getEntity(); + Assert.assertNotNull(entity); } @Test @@ -333,9 +381,13 @@ public class SearchGraphTest extends AAISetup { List<String> filter = new ArrayList<>(); filter.add("model:EXISTS:DOES-NOT-EXIST:AAI"); List<String> edgeFilter = new ArrayList<>(); - searchGraph.runNodesQuery(new NodesQueryBuilder().setHeaders(httpHeaders) - .setTargetNodeType("model-ver").setEdgeFilterParams(edgeFilter).setFilterParams(filter) - .setDbEngine(dbEngine).setLoader(loader).setUrlBuilder(urlBuilder)); + Response response = searchGraph.runNodesQuery(new NodesQueryBuilder().setHeaders(httpHeaders) + .setTargetNodeType("model-ver").setEdgeFilterParams(edgeFilter).setFilterParams(filter) + .setDbEngine(dbEngine).setLoader(loader).setUrlBuilder(urlBuilder)); + Assert.assertNotNull(response); + Assert.assertEquals(200,response.getStatus()); + Object entity = response.getEntity(); + Assert.assertNotNull(entity); } @Test(expected = AAIException.class) @@ -344,8 +396,12 @@ public class SearchGraphTest extends AAISetup { List<String> filter = new ArrayList<>(); filter.add("model:DOES_NOT_EXIST:DOES-NOT-EXIST:AAI"); List<String> edgeFilter = new ArrayList<>(); - searchGraph.runNodesQuery(new NodesQueryBuilder().setHeaders(httpHeaders) - .setTargetNodeType("model-ver").setEdgeFilterParams(edgeFilter).setFilterParams(filter) - .setDbEngine(dbEngine).setLoader(loader).setUrlBuilder(urlBuilder)); + Response response = searchGraph.runNodesQuery(new NodesQueryBuilder().setHeaders(httpHeaders) + .setTargetNodeType("model-ver").setEdgeFilterParams(edgeFilter).setFilterParams(filter) + .setDbEngine(dbEngine).setLoader(loader).setUrlBuilder(urlBuilder)); + Assert.assertNotNull(response); + Assert.assertEquals(200,response.getStatus()); + Object entity = response.getEntity(); + Assert.assertNotNull(entity); } } diff --git a/aai-traversal/src/test/java/org/onap/aai/interceptors/post/InvalidResponseStatusTest.java b/aai-traversal/src/test/java/org/onap/aai/interceptors/post/InvalidResponseStatusTest.java new file mode 100644 index 0000000..1564aab --- /dev/null +++ b/aai-traversal/src/test/java/org/onap/aai/interceptors/post/InvalidResponseStatusTest.java @@ -0,0 +1,101 @@ +/** + * ============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.interceptors.post; + +import org.junit.Before; +import org.junit.Test; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import javax.ws.rs.container.ContainerRequestContext; +import javax.ws.rs.container.ContainerResponseContext; +import java.io.IOException; +import static org.junit.Assert.*; +import static org.mockito.Mockito.*; + +public class InvalidResponseStatusTest { + + @InjectMocks + private InvalidResponseStatus invalidResponseStatus; + + @Mock + private ContainerRequestContext mockRequestContext; + + @Mock + private ContainerResponseContext mockResponseContext; + + private final int[] status = {405}; + + @Before + public void setUp() { + MockitoAnnotations.openMocks(this); + // Mock getStatus to return the current value in the status array + when(mockResponseContext.getStatus()).thenAnswer(invocation -> status[0]); + + // Use doAnswer to update the status value when setStatus is called + doAnswer(invocation -> { + Object[] args = invocation.getArguments(); + if (args.length > 0 && args[0] instanceof Integer) { + status[0] = (Integer) args[0]; // Update the mock's status + } + return null; + }).when(mockResponseContext).setStatus(anyInt()); + } + + @Test + public void testFilter_statusIs405_shouldChangeTo400() throws IOException { + invalidResponseStatus.filter(mockRequestContext, mockResponseContext); + + verify(mockResponseContext).setStatus(400); + + // Check the final status of the response context + assertEquals(400, mockResponseContext.getStatus()); // Ensure status is now 400 + } + + @Test + public void testFilter_ResponseStatus405_ShouldHandleContentType() throws IOException { + // Setup: Simulate a 405 status and set Content-Type header to "application/json" + String contentType = "application/json"; + when(mockResponseContext.getStatus()).thenReturn(405); + when(mockResponseContext.getHeaderString("Content-Type")).thenReturn(contentType); + + invalidResponseStatus.filter(mockRequestContext, mockResponseContext); + + verify(mockResponseContext).setStatus(400); + + verify(mockResponseContext).setEntity(anyString()); + + assertEquals("application/json",mockResponseContext.getHeaderString("Content-Type")); + } + + @Test + public void testFilter_ResponseStatusNot405_ShouldNotChangeStatus() throws IOException { + when(mockResponseContext.getStatus()).thenReturn(200); + + invalidResponseStatus.filter(mockRequestContext, mockResponseContext); + + verify(mockResponseContext, never()).setStatus(400); + + verify(mockResponseContext, never()).setEntity(anyString()); + + assertTrue("Response status should remain 200", mockResponseContext.getStatus() == 200); + assertNull("Entity should not be set", mockResponseContext.getEntity()); + } +} diff --git a/aai-traversal/src/test/java/org/onap/aai/interceptors/post/ResponseHeaderManipulationTest.java b/aai-traversal/src/test/java/org/onap/aai/interceptors/post/ResponseHeaderManipulationTest.java new file mode 100644 index 0000000..3360826 --- /dev/null +++ b/aai-traversal/src/test/java/org/onap/aai/interceptors/post/ResponseHeaderManipulationTest.java @@ -0,0 +1,101 @@ +/** + * ============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.interceptors.post; + +import org.junit.Before; +import org.junit.Test; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import javax.ws.rs.container.ContainerRequestContext; +import javax.ws.rs.container.ContainerResponseContext; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.MultivaluedMap; +import java.io.IOException; +import java.util.Collections; +import static org.junit.Assert.*; +import static org.mockito.Mockito.when; + +public class ResponseHeaderManipulationTest { + + @InjectMocks + private ResponseHeaderManipulation responseHeaderManipulation; + + @Mock + private ContainerRequestContext mockRequestContext; + + @Mock + private ContainerResponseContext mockResponseContext; + + @Mock + private MultivaluedMap<String, Object> mockResponseHeaders; + + @Before + public void setUp() { + MockitoAnnotations.openMocks(this); + when(mockResponseContext.getHeaders()).thenReturn(mockResponseHeaders); + } + + @Test + public void testFilterWithNoContentType() throws IOException { + // Arrange: Simulate Accept header with "*/*" and no Content-Type set + when(mockRequestContext.getHeaderString("Accept")).thenReturn("*/*"); + + responseHeaderManipulation.filter(mockRequestContext, mockResponseContext); + + assertFalse(mockResponseHeaders.containsKey("Content-Type")); + } + + @Test + public void testFilterWithExistingContentType() throws IOException { + // Arrange: Simulate existing Content-Type header and no Accept header + String existingContentType = MediaType.APPLICATION_JSON; + when(mockRequestContext.getHeaderString("Accept")).thenReturn(null); + when(mockResponseContext.getHeaderString("Content-Type")).thenReturn(existingContentType); + + responseHeaderManipulation.filter(mockRequestContext, mockResponseContext); + + assertEquals(existingContentType, mockResponseContext.getHeaderString("Content-Type")); + } + + @Test + public void testFilterWithNullAcceptHeader() throws IOException { + // Arrange: Simulate null Accept header and no Content-Type set + when(mockRequestContext.getHeaderString("Accept")).thenReturn(null); + when(mockResponseContext.getHeaderString("Content-Type")).thenReturn(null); + + responseHeaderManipulation.filter(mockRequestContext, mockResponseContext); + + assertFalse(mockResponseHeaders.containsKey("Content-Type")); + assertNotEquals(Collections.singletonList(MediaType.APPLICATION_XML), mockResponseHeaders.get("Content-Type")); + } + + @Test + public void testFilterWithEmptyAcceptHeader() throws IOException { + // Arrange: Simulate empty Accept header and no Content-Type set + when(mockRequestContext.getHeaderString("Accept")).thenReturn(""); + when(mockResponseContext.getHeaderString("Content-Type")).thenReturn(null); + + responseHeaderManipulation.filter(mockRequestContext, mockResponseContext); + + assertFalse(mockResponseHeaders.containsKey("Content-Type")); + assertNotEquals(Collections.singletonList(MediaType.APPLICATION_XML), mockResponseHeaders.get("Content-Type")); + } +} diff --git a/aai-traversal/src/test/java/org/onap/aai/interceptors/pre/HeaderValidationTest.java b/aai-traversal/src/test/java/org/onap/aai/interceptors/pre/HeaderValidationTest.java new file mode 100644 index 0000000..068cf09 --- /dev/null +++ b/aai-traversal/src/test/java/org/onap/aai/interceptors/pre/HeaderValidationTest.java @@ -0,0 +1,210 @@ +/** + * ============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.interceptors.pre; + +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.TraversalApp; +import org.onap.aai.interceptors.AAIHeaderProperties; +import org.onap.logging.filter.base.Constants; +import org.onap.logging.ref.slf4j.ONAPLogConstants; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.TestPropertySource; +import javax.ws.rs.container.ContainerRequestContext; +import javax.ws.rs.core.MultivaluedHashMap; +import javax.ws.rs.core.MultivaluedMap; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import static org.junit.Assert.assertTrue; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.mockito.Mockito.*; + +@SpringBootTest( + webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, + classes = TraversalApp.class) +@TestPropertySource(locations = "classpath:application-test.properties") +public class HeaderValidationTest { + + @InjectMocks + private HeaderValidation headerValidation; + + @Mock + private ContainerRequestContext requestContext; + + private MultivaluedMap<String, String> headers; + + @BeforeEach + public void setUp() { + // Initialize mocks + MockitoAnnotations.openMocks(this); + headerValidation = new HeaderValidation(); + headers = new MultivaluedHashMap<>(); + when(requestContext.getHeaders()).thenReturn(headers); + } + + @Test + public void testGetPartnerName_withEmptyPartnerName() { + when(requestContext.getHeaderString("X-ONAP-PartnerName")).thenReturn(""); + when(requestContext.getHeaderString("X-FromAppId")).thenReturn("testAppId"); + + String partnerName = headerValidation.getPartnerName(requestContext); + + // Assert that the app ID is used as the partner name + assertEquals("testAppId", partnerName); + } + + @Test + public void testGetPartnerName_withNullPartnerNameAndFromAppId() { + // Mock behavior of getHeaderString to return null for both PARTNER_NAME and FROM_APP_ID + when(requestContext.getHeaderString("X-ONAP-PartnerName")).thenReturn(null); + when(requestContext.getHeaderString("X-FromAppId")).thenReturn("testAppId"); + + String partnerName = headerValidation.getPartnerName(requestContext); + + // Assert that the partner name is taken from the FROM_APP_ID + assertEquals("testAppId", partnerName); + } + + @Test + public void testGetPartnerName_withMissingPartnerNameAndFromAppId() { + // Mock behavior of getHeaderString to return null for both PARTNER_NAME and FROM_APP_ID + when(requestContext.getHeaderString("X-ONAP-PartnerName")).thenReturn(null); + when(requestContext.getHeaderString("FROM_APP_ID")).thenReturn(null); + + String partnerName = headerValidation.getPartnerName(requestContext); + + // Assert that the partner name is null when both headers are missing + assertNull(partnerName); + } + + @Test + public void testGetRequestId_withValidRequestId() { + // Mock behavior of getHeaderString to return a valid request ID + when(requestContext.getHeaderString("X-ONAP-RequestID")).thenReturn("testRequestId"); + String requestId = headerValidation.getRequestId(requestContext); + + // Assert the expected outcome + assertEquals("testRequestId", requestId); + } + + @Test + public void testGetRequestId_withNullRequestId() { + // Mock behavior of getHeaderString to return null for X-ONAP-RequestId and a valid TRANSACTION_ID + when(requestContext.getHeaderString("X-ONAP-RequestId")).thenReturn(null); + when(requestContext.getHeaderString("TRANSACTION_ID")).thenReturn("testTransactionId"); + + // Call the method to test + String requestId = headerValidation.getRequestId(requestContext); + + // Assert that the transaction ID is used as the request ID + assertEquals(null, requestId); + } + + @Test + public void testFilter_withMissingPartnerName() throws IOException { + // Mock behavior for missing PartnerName header + when(requestContext.getHeaderString("X-ONAP-PartnerName")).thenReturn(""); + when(requestContext.getHeaderString("FROM_APP_ID")).thenReturn("testAppId"); + when(requestContext.getHeaderString("X-ONAP-RequestId")).thenReturn("testRequestId"); + + // Call the method to test + headerValidation.filter(requestContext); + + // Verify that the method calls abortWith due to the missing partner name + verify(requestContext).abortWith(argThat(response -> response.getStatus() == 400)); + } + + @Test + void testGetRequestId_ClearsExistingHeaders() { + // Arrange + String expectedRequestId = "test-request-id"; + headers.put(ONAPLogConstants.Headers.REQUEST_ID, new ArrayList<>()); + headers.put(Constants.HttpHeaders.TRANSACTION_ID, new ArrayList<>()); + headers.put(Constants.HttpHeaders.HEADER_REQUEST_ID, new ArrayList<>()); + headers.put(Constants.HttpHeaders.ECOMP_REQUEST_ID, new ArrayList<>()); + + when(requestContext.getHeaderString(ONAPLogConstants.Headers.REQUEST_ID)) + .thenReturn(expectedRequestId); + + // Act + String actualRequestId = headerValidation.getRequestId(requestContext); + + // Assert + assertEquals(expectedRequestId, actualRequestId); + verify(requestContext, atLeastOnce()).getHeaders(); + assertTrue(headers.get(ONAPLogConstants.Headers.REQUEST_ID).isEmpty()); + assertTrue(headers.get(Constants.HttpHeaders.TRANSACTION_ID).contains(expectedRequestId)); + assertTrue(headers.get(Constants.HttpHeaders.HEADER_REQUEST_ID).isEmpty()); + assertTrue(headers.get(Constants.HttpHeaders.ECOMP_REQUEST_ID).isEmpty()); + } + + @Test + void testGetRequestId_WhenEcompRequestIdExists() { + String expectedRequestId = "ecomp-123"; + when(requestContext.getHeaderString(ONAPLogConstants.Headers.REQUEST_ID)) + .thenReturn(null); + when(requestContext.getHeaderString(Constants.HttpHeaders.HEADER_REQUEST_ID)) + .thenReturn(null); + when(requestContext.getHeaderString(Constants.HttpHeaders.TRANSACTION_ID)) + .thenReturn(null); + when(requestContext.getHeaderString(Constants.HttpHeaders.ECOMP_REQUEST_ID)) + .thenReturn(expectedRequestId); + String result = headerValidation.getRequestId(requestContext); + assertEquals(expectedRequestId, result); + } + + @Test + void whenPartnerNameHasValidComponents_shouldReturnFirstComponent() { + // Given + when(requestContext.getHeaderString(ONAPLogConstants.Headers.PARTNER_NAME)).thenReturn("TEST.COMPONENT"); + String result = headerValidation.getPartnerName(requestContext); + assertEquals("TEST.COMPONENT", result); + } + + @Test + void whenPartnerNameStartsWithAAI_shouldUseFromAppId() { + when(requestContext.getHeaderString(ONAPLogConstants.Headers.PARTNER_NAME)).thenReturn("AAI.COMPONENT"); + when(requestContext.getHeaderString(AAIHeaderProperties.FROM_APP_ID)).thenReturn("TEST-APP"); + String result = headerValidation.getPartnerName(requestContext); + assertEquals("AAI.COMPONENT", result); + } + + @Test + void shouldClearAndUpdateHeaders() { + // Given + List<String> oldValues = new ArrayList<>(); + oldValues.add("OLD-VALUE"); + headers.put(ONAPLogConstants.Headers.PARTNER_NAME, oldValues); + headers.put(AAIHeaderProperties.FROM_APP_ID, oldValues); + + when(requestContext.getHeaderString(ONAPLogConstants.Headers.PARTNER_NAME)).thenReturn("NEW-SOT"); + when(requestContext.getHeaderString(AAIHeaderProperties.FROM_APP_ID)).thenReturn("TEST-APP"); + String result = headerValidation.getPartnerName(requestContext); + + assertEquals("NEW-SOT", result); + assertEquals("NEW-SOT", headers.getFirst(AAIHeaderProperties.FROM_APP_ID)); + } + +} diff --git a/aai-traversal/src/test/java/org/onap/aai/interceptors/pre/RequestTransactionLoggingTest.java b/aai-traversal/src/test/java/org/onap/aai/interceptors/pre/RequestTransactionLoggingTest.java new file mode 100644 index 0000000..8d14613 --- /dev/null +++ b/aai-traversal/src/test/java/org/onap/aai/interceptors/pre/RequestTransactionLoggingTest.java @@ -0,0 +1,199 @@ +/** + * ============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.interceptors.pre; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.MockitoAnnotations; +import org.onap.aai.TraversalApp; +import org.onap.aai.interceptors.AAIHeaderProperties; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.context.TestConfiguration; +import org.springframework.context.annotation.Bean; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.TestPropertySource; +import org.springframework.test.context.junit.jupiter.SpringExtension; +import javax.ws.rs.container.ContainerRequestContext; +import javax.ws.rs.core.MultivaluedMap; +import javax.ws.rs.core.UriInfo; +import java.io.IOException; +import java.lang.reflect.Method; +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.Mockito.*; + +@ExtendWith(SpringExtension.class) +@SpringBootTest( + webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, + classes = TraversalApp.class) +@TestPropertySource(locations = "classpath:application-test.properties") +@ContextConfiguration(classes = RequestTransactionLoggingTest.TestConfig.class) +public class RequestTransactionLoggingTest { + + @InjectMocks + private RequestTransactionLogging requestTransactionLogging; + + @Mock + private ContainerRequestContext mockRequestContext; + + @Mock + private MultivaluedMap<String, String> mockHeaders; + + @Mock + private UriInfo mockUriInfo; + + @BeforeEach + void setUp() { + MockitoAnnotations.openMocks(this); // Initialize mocks + resetMocks(); // Reset mock states + + when(mockRequestContext.getHeaders()).thenReturn(mockHeaders); + when(mockRequestContext.getUriInfo()).thenReturn(mockUriInfo); + + when(mockHeaders.getFirst("Content-Type")).thenReturn(null); + when(mockHeaders.getFirst("Accept")).thenReturn("application/xml"); + + doNothing().when(mockHeaders).putSingle(anyString(), anyString()); + when(mockHeaders.containsKey("Content-Type")).thenReturn(false); + when(mockHeaders.containsKey("Accept")).thenReturn(true); + } + + private void resetMocks() { + Mockito.reset(mockRequestContext, mockHeaders, mockUriInfo); + } + + @Test + void testFilter_noContentTypeHeader_shouldNotModifyRequest() throws IOException { + // Prepare mock responses + when(mockHeaders.getFirst("Content-Type")).thenReturn(null); + when(mockHeaders.getFirst("Accept")).thenReturn("application/xml"); + when(mockRequestContext.getUriInfo()).thenReturn(null); + + requestTransactionLogging.filter(mockRequestContext); + + // Verify that Content-Type is added and Accept is preserved + verify(mockHeaders).putSingle("Content-Type", "application/json"); + verify(mockHeaders).putSingle("Accept", "application/xml"); + } + + @Test + void testFilter_shouldSetTransactionIdAndRequestProperties() throws IOException { + // Set mock data for headers and uri info + when(mockHeaders.getFirst("Content-Type")).thenReturn("application/json"); + when(mockHeaders.getFirst("Accept")).thenReturn("*/*"); + when(mockUriInfo.getPath()).thenReturn("/test/path"); + + requestTransactionLogging.filter(mockRequestContext); + + // Verify that the correct properties are set + verify(mockRequestContext).setProperty(eq(AAIHeaderProperties.AAI_TX_ID), anyString()); + verify(mockRequestContext).setProperty(eq(AAIHeaderProperties.AAI_REQUEST), anyString()); + verify(mockRequestContext).setProperty(eq(AAIHeaderProperties.AAI_REQUEST_TS), anyString()); + + // Verify that headers are set properly + verify(mockRequestContext.getHeaders()).putSingle(eq("Content-Type"), eq("application/json")); + verify(mockRequestContext.getHeaders()).putSingle(eq("Accept"), eq("application/xml")); + } + + @Test + void testFilter_withDslPath_shouldSetAcceptHeaderToJson() throws IOException { + // Mock URI path for DSL request + when(mockUriInfo.getPath()).thenReturn("/some/dsl"); + when(mockHeaders.getFirst("Content-Type")).thenReturn("application/json"); + + requestTransactionLogging.filter(mockRequestContext); + + // Verify that the Accept header is set to application/json + verify(mockRequestContext.getHeaders()).putSingle("Accept", "application/json"); + } + + @Test + void testFilter_withQueryPath_shouldSetAcceptHeaderToJson() throws IOException { + // Mock URI path for query request + when(mockUriInfo.getPath()).thenReturn("/some/query"); + + requestTransactionLogging.filter(mockRequestContext); + + // Verify that the Accept header is set to application/json + verify(mockRequestContext.getHeaders()).putSingle("Accept", "application/json"); + } + + @Test + void testFilter_withRecentsPath_shouldSetAcceptHeaderToJson() throws IOException { + // Mock URI path for recents request + when(mockUriInfo.getPath()).thenReturn("/some/recents/data"); + + requestTransactionLogging.filter(mockRequestContext); + + // Verify that the Accept header is set to application/json + verify(mockRequestContext.getHeaders()).putSingle("Accept", "application/json"); + } + + @Test + void testFilter_withOtherPath_shouldSetAcceptHeaderToDefault() throws IOException { + // Mock URI path for other request + when(mockUriInfo.getPath()).thenReturn("/some/other/path"); + + requestTransactionLogging.filter(mockRequestContext); + + // Verify that Accept and Content-Type are set to their default values + verify(mockRequestContext.getHeaders()).putSingle("Accept", "application/xml"); + verify(mockRequestContext.getHeaders()).putSingle("Content-Type", "application/json"); + } + + @Test + void testGetAAITxIdToHeader_shouldGenerateTxIdWithTimestamp() throws Exception { + String currentTimeStamp = "20251211"; + Method method = RequestTransactionLogging.class.getDeclaredMethod("getAAITxIdToHeader", String.class); + method.setAccessible(true); + + String txId = (String) method.invoke(requestTransactionLogging, currentTimeStamp); + + assertNotNull(txId); + assertTrue(txId.contains(currentTimeStamp), "Transaction ID should contain the timestamp"); + } + + @Test + void testGetRequest_shouldCreateRequestJson() throws Exception { + String fullId = "12345-abc"; + Method method = RequestTransactionLogging.class.getDeclaredMethod("getRequest", ContainerRequestContext.class, String.class); + method.setAccessible(true); + + String requestJson = (String) method.invoke(requestTransactionLogging, mockRequestContext, fullId); + + // Verify that the generated request JSON contains expected fields + assertNotNull(requestJson); + assertTrue(requestJson.contains("ID")); + assertTrue(requestJson.contains("Http-Method")); + assertTrue(requestJson.contains("Headers")); + } + + // Custom configuration for this test class to isolate the beans + @TestConfiguration + static class TestConfig { + @Bean + public RequestTransactionLogging requestTransactionLogging() { + return new RequestTransactionLogging(); + } + } +} |