Skip to content

Commit

Permalink
Integrate dynamic integrationtests
Browse files Browse the repository at this point in the history
  • Loading branch information
tunacicek committed Jan 15, 2025
1 parent 097e642 commit 56dbd05
Show file tree
Hide file tree
Showing 168 changed files with 5,998 additions and 1,242 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
/*******************************************************************************
* Copyright (c) 2024 Robert Bosch Manufacturing Solutions GmbH and others
* Copyright (c) 2024 Contributors to the Eclipse Foundation
*
* See the NOTICE file(s) distributed with this work for additional
* information regarding copyright ownership.
*
* This program and the accompanying materials are made available under the
* terms of the Apache License, Version 2.0 which is available at
* https://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.
*
* SPDX-License-Identifier: Apache-2.0
******************************************************************************/

package org.eclipse.tractusx.semantics.integrationtests;

import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Stream;

import org.eclipse.tractusx.semantics.RegistryProperties;
import org.eclipse.tractusx.semantics.integrationtests.model.ApiRequest;
import org.eclipse.tractusx.semantics.integrationtests.model.ExpectedResponse;
import org.eclipse.tractusx.semantics.registry.JwtTokenFactory;
import org.junit.jupiter.api.DynamicTest;
import org.junit.jupiter.api.TestFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.ResultActions;
import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;

@SpringBootTest
@AutoConfigureMockMvc
@EnableConfigurationProperties( RegistryProperties.class )
public class AssetAdministrationShellIntegrationTest {

@Autowired
private MockMvc mockMvc;

@Autowired
protected JwtTokenFactory jwtTokenFactory;

private final ResponseValidator responseValidator = new ResponseValidator();

private final ObjectMapper objectMapper = new ObjectMapper();
private static final String ROOT_DIR = "src/test/resources/integrationtests/";
private static final List<String> LIST_OF_TEST_CASES_DIR = List.of( "aas-registry-usecases" );
private static final String REQUEST_FILE_NAME = "request.json";
private static final String EXPECTED_RESPONSE_FILE_NAME = "expected-response.json";
protected static final String EXTERNAL_SUBJECT_ID_HEADER = "Edc-Bpn";

@TestFactory
List<DynamicTest> executeTests() {

List<DynamicTest> dynamicTests = new ArrayList<>();

LIST_OF_TEST_CASES_DIR.forEach( testcasePath -> {
try {
Stream<DynamicTest> tests = Files.list( Paths.get( ROOT_DIR + testcasePath ) )
.filter( Files::isDirectory )
.map( useCasePath -> {
try {
return DynamicTest.dynamicTest( testcasePath + "_" + useCasePath.getFileName().toString(),
() -> executeUseCaseTest( useCasePath ) );
} catch ( Exception e ) {
throw new RuntimeException( "Failed to load usecase:" + useCasePath, e );
}
} );

dynamicTests.addAll( tests.toList() );
} catch ( IOException e ) {
throw new RuntimeException( "Failed to load test steps", e );
}
} );

return dynamicTests;
}

private void executeUseCaseTest( Path useCasePath ) throws Exception {
Files.list( useCasePath )
.filter( Files::isDirectory )
.sorted( Comparator.comparing( Path::getFileName ) )
.forEach( testStepPath -> {
try {
executeTestStep( testStepPath );
} catch ( Exception e ) {
throw new RuntimeException( "Failed to load test steps", e );
}
} );
}

private void executeTestStep( Path testStepPath ) throws Exception {
// Load request.json
File requestFile = testStepPath.resolve( REQUEST_FILE_NAME ).toFile();
ApiRequest request = objectMapper.readValue( requestFile, ApiRequest.class );

// Load expected-response.json
File expectedResponseFile = testStepPath.resolve( EXPECTED_RESPONSE_FILE_NAME ).toFile();
ExpectedResponse expectedResponse = objectMapper.readValue( expectedResponseFile, ExpectedResponse.class );

// Perform request
ResultActions actual = performRequest( request );

// Validate response
responseValidator.validateResponse( actual, expectedResponse );
}

private ResultActions performRequest( ApiRequest request ) throws Exception {
HttpMethod httpMethod = HttpMethod.valueOf( request.getMethod().toUpperCase() );
MockHttpServletRequestBuilder requestBuilder = createRequestBuilder( httpMethod, request );
JwtTokenFactory.Tenant tenant = jwtTokenFactory.getTenant( request.getTenant() );
return mockMvc.perform(
requestBuilder
.header( EXTERNAL_SUBJECT_ID_HEADER, tenant.getTenantId() )
.accept( MediaType.APPLICATION_JSON )
.with( tenant.allRoles() )
);
}

private MockHttpServletRequestBuilder createRequestBuilder( HttpMethod httpMethod, ApiRequest request ) throws JsonProcessingException {
String requestUrl = request.getUrl();
switch ( httpMethod.name() ) {
case "GET":
return get( requestUrl );
case "POST":
return post( requestUrl )
.contentType( MediaType.APPLICATION_JSON )
.content( objectMapper.writeValueAsString( request.getBody() ) );
case "PUT":
return put( requestUrl )
.contentType( MediaType.APPLICATION_JSON )
.content( objectMapper.writeValueAsString( request.getBody() ) );
case "DELETE":
return delete( requestUrl );
default:
throw new UnsupportedOperationException( "HTTP method not supported: " + request.getMethod() );
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
/*******************************************************************************
* Copyright (c) 2024 Robert Bosch Manufacturing Solutions GmbH and others
* Copyright (c) 2024 Contributors to the Eclipse Foundation
*
* See the NOTICE file(s) distributed with this work for additional
* information regarding copyright ownership.
*
* This program and the accompanying materials are made available under the
* terms of the Apache License, Version 2.0 which is available at
* https://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.
*
* SPDX-License-Identifier: Apache-2.0
******************************************************************************/

package org.eclipse.tractusx.semantics.integrationtests;

import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.Matchers.*;
import static org.hamcrest.collection.IsCollectionWithSize.hasSize;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;

import java.util.List;

import org.eclipse.tractusx.semantics.integrationtests.model.Assertion;
import org.eclipse.tractusx.semantics.integrationtests.model.ExpectedResponse;
import org.springframework.test.web.servlet.ResultActions;

import com.fasterxml.jackson.databind.ObjectMapper;

public class ResponseValidator {

private final ObjectMapper objectMapper = new ObjectMapper();

public void validateResponse( ResultActions actual, ExpectedResponse expectedResponse ) throws Exception {
actual.andExpect( status().is( expectedResponse.getStatus() ) );

if ( expectedResponse.isContent() ) {
if ( expectedResponse.getExpectedPayload() != null ) {
actual.andExpect( content().json( objectMapper.writeValueAsString( expectedResponse.getExpectedPayload() ) ) );
}
executeAssertions( actual, expectedResponse.getAssertions() );
}
}

private void executeAssertions( ResultActions actual, List<Assertion> assertions ) throws Exception {
for ( Assertion assertion : assertions ) {
if ( assertion.getExists() != null && assertion.getExists() ) {
actual.andExpect( jsonPath( assertion.getJsonPath() ).exists() );
} else if ( assertion.getEquals() != null ) {
actual.andExpect( jsonPath( assertion.getJsonPath(), equalTo( assertion.getEquals() ) ) );
} else if ( assertion.getHasSize() != null ) {
actual.andExpect( jsonPath( assertion.getJsonPath(), hasSize( assertion.getHasSize() ) ) );
} else if ( assertion.getContains() != null ) {
actual.andExpect( jsonPath( assertion.getJsonPath(), contains( assertion.getContains() ) ) );
} else if ( assertion.getDoesNotExist() != null && assertion.getDoesNotExist() ) {
actual.andExpect( jsonPath( assertion.getJsonPath() ).doesNotExist() );
} else if ( assertion.getHasItem() != null ) {
actual.andExpect( jsonPath( assertion.getJsonPath(), hasItem( assertion.getHasItem() ) ) );
} else if ( assertion.getIsEmpty() != null && assertion.getIsEmpty() ) {
actual.andExpect( jsonPath( assertion.getJsonPath() ).isEmpty() );
} else if ( assertion.getIsNotEmpty() != null && assertion.getIsNotEmpty() ) {
actual.andExpect( jsonPath( assertion.getJsonPath() ).isNotEmpty() );
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/*******************************************************************************
* Copyright (c) 2024 Robert Bosch Manufacturing Solutions GmbH and others
* Copyright (c) 2024 Contributors to the Eclipse Foundation
*
* See the NOTICE file(s) distributed with this work for additional
* information regarding copyright ownership.
*
* This program and the accompanying materials are made available under the
* terms of the Apache License, Version 2.0 which is available at
* https://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.
*
* SPDX-License-Identifier: Apache-2.0
******************************************************************************/

package org.eclipse.tractusx.semantics.integrationtests.model;

import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
public class ApiRequest {
private String url;
private String tenant;
private String method;
private Object body;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/*******************************************************************************
* Copyright (c) 2024 Robert Bosch Manufacturing Solutions GmbH and others
* Copyright (c) 2024 Contributors to the Eclipse Foundation
*
* See the NOTICE file(s) distributed with this work for additional
* information regarding copyright ownership.
*
* This program and the accompanying materials are made available under the
* terms of the Apache License, Version 2.0 which is available at
* https://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.
*
* SPDX-License-Identifier: Apache-2.0
******************************************************************************/

package org.eclipse.tractusx.semantics.integrationtests.model;

import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
public class Assertion {
private String jsonPath;
private Boolean exists;
private Boolean doesNotExist;
private Boolean isEmpty;
private Boolean isNotEmpty;
private String equals;
private Integer hasSize;
private Object contains;
private Object hasItem;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/*******************************************************************************
* Copyright (c) 2024 Robert Bosch Manufacturing Solutions GmbH and others
* Copyright (c) 2024 Contributors to the Eclipse Foundation
*
* See the NOTICE file(s) distributed with this work for additional
* information regarding copyright ownership.
*
* This program and the accompanying materials are made available under the
* terms of the Apache License, Version 2.0 which is available at
* https://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.
*
* SPDX-License-Identifier: Apache-2.0
******************************************************************************/

package org.eclipse.tractusx.semantics.integrationtests.model;

import java.util.List;

import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
public class ExpectedResponse {
private int status;
private boolean content;
private List<Assertion> assertions;
private Object expectedPayload;
}
Loading

0 comments on commit 56dbd05

Please sign in to comment.