| /******************************************************************************** |
| * Copyright (c) 2015-2019 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 Eclipse Public License v. 2.0 which is available at |
| * http://www.eclipse.org/legal/epl-2.0. |
| * |
| * SPDX-License-Identifier: EPL-2.0 |
| * |
| ********************************************************************************/ |
| |
| package org.eclipse.mdm.businessobjects.boundary.integrationtest; |
| |
| import static org.hamcrest.MatcherAssert.assertThat; |
| import static org.hamcrest.Matchers.is; |
| import static org.hamcrest.Matchers.notNullValue; |
| |
| import java.util.NoSuchElementException; |
| |
| import org.slf4j.Logger; |
| import org.slf4j.LoggerFactory; |
| |
| import io.restassured.RestAssured; |
| import io.restassured.authentication.FormAuthConfig; |
| import io.restassured.authentication.FormAuthScheme; |
| import io.vavr.collection.HashMap; |
| import io.vavr.collection.HashSet; |
| import io.vavr.collection.Map; |
| import io.vavr.collection.Set; |
| |
| /* |
| * @author Johannes Stamm, Peak Solution GmbH Nuernberg |
| */ |
| |
| public abstract class ResourceIntegrationTest { |
| private static Logger LOGGER = LoggerFactory.getLogger(ResourceIntegrationTest.class); |
| |
| private static final String HOST = "localhost"; |
| private static final String PORT = "8080"; |
| private static final String BASE_PATH = "org.eclipse.mdm.nucleus"; |
| private static final String API_PATH = "mdm"; |
| private static final String ENV_PATH = "environments"; |
| protected static final String SOURCE_NAME = "MDMNVH"; |
| |
| private static final String AUTH_USERNAME = "sa"; |
| private static final String AUTH_PASSWORD = "sa"; |
| |
| protected static final String TESTDATA_ENTITY_ID = "entityId"; |
| protected static final String TESTDATA_ENTITY_NAME = "entityName"; |
| protected static final String TESTDATA_ENTITY_TYPE = "entityType"; |
| protected static final String TESTDATA_CONTEXT_GROUP = "contextGroup"; |
| protected static final String TESTDATA_CREATE_JSON_BODY = "createJSONBody"; |
| protected static final String TESTDATA_NUMBER_OF_VALUES = "NumberOfValues"; |
| protected static final String TESTDATA_UPDATE_JSON_BODY = "updateJSONBody"; |
| protected static final String TESTDATA_RESOURCE_URI = "resourceURI"; |
| protected static final String TESTDATA_RANDOM_DATA = "RANDOM_DATA"; |
| |
| private static final String RANDOM_ENTITY_NAME_SUFFIX = "_" + Long.toHexString(System.currentTimeMillis()); |
| |
| public enum TestType { |
| CREATE, FIND, FINDALL, UPDATE, DELETE, UPDATE_CONTEXT, FIND_CONTEXT; |
| } |
| |
| protected static Map<Class<?>, Set<TestType>> testsToSkip = HashMap.empty(); |
| |
| protected static Map<Class<?>, Map<String, String>> testDataMap = HashMap.empty(); |
| |
| // if this is set, the resource URI for find() is constructed with the name as |
| // the PATH_PARAM |
| protected static Map<Class<?>, Boolean> findByName = HashMap.empty(); |
| |
| /** |
| * The context class must be set by implementing tests as the context to get |
| * from and put test data values to |
| */ |
| private static Class<?> contextClass; |
| |
| static { |
| // configure URI |
| StringBuilder baseURI = new StringBuilder(); |
| baseURI.append("http://").append(HOST).append(":").append(PORT).append("/").append(BASE_PATH).append("/") |
| .append(API_PATH); |
| RestAssured.baseURI = baseURI.toString(); |
| RestAssured.basePath = ENV_PATH + "/" + SOURCE_NAME; |
| |
| LOGGER.debug("RestAssured set up to " + RestAssured.baseURI + "/" + RestAssured.basePath); |
| |
| // setup authentication |
| // PreemptiveBasicAuthScheme authScheme = new PreemptiveBasicAuthScheme(); |
| FormAuthScheme authScheme = new FormAuthScheme(); |
| authScheme.setConfig(new FormAuthConfig("/" + BASE_PATH + "/j_security_check", "j_username", "j_password")); |
| authScheme.setUserName(AUTH_USERNAME); |
| authScheme.setPassword(AUTH_PASSWORD); |
| |
| RestAssured.authentication = authScheme; |
| |
| LOGGER.debug("RestAssured authentication set to credentials [" + AUTH_USERNAME + "]/[" + AUTH_PASSWORD + "]"); |
| } |
| |
| /** |
| * Gets value with key from the testDataMap. The value map is thereby |
| * automatically identified by the implementing class. |
| * |
| * @param key key to get value for |
| * @return value for given key |
| */ |
| protected static String getTestDataValue(String key) { |
| return getTestDataValue(getContextClass(), key); |
| } |
| |
| /** |
| * Gets value with key from the testDataMap using the context specified by |
| * contextClass |
| * |
| * @param contextClass the class of the test implementation |
| * @param key key to get value for |
| * @return value for given key |
| */ |
| protected static String getTestDataValue(Class<?> contextClass, String key) { |
| return testDataMap.get(contextClass) |
| .map(valueMap -> valueMap.get(key).getOrElseThrow(() -> new NoSuchElementException("Key [" + key |
| + "] not found in test data value map in context [" + contextClass.getSimpleName() + "]"))) |
| .get(); |
| } |
| |
| /** |
| * Checks if a test data value is present for the given key |
| * |
| * @param key key to check presence of test data value for |
| * @return true, if a test data value for the given key exists, false if not |
| */ |
| protected static boolean isTestDataValuePresent(String key) { |
| return testDataMap.get(getContextClass()).map(valueMap -> valueMap.get(key).isDefined()).get(); |
| } |
| |
| /** |
| * Removes the test data value for the given key. If the key is not present, |
| * nothing happens. |
| * |
| * @param key key to remove test data value for |
| */ |
| protected static void removeTestDataValue(String key) { |
| testDataMap.get(getContextClass()).map(valueMap -> valueMap.remove(key)) |
| .map(newValueMap -> testDataMap = testDataMap.put(getContextClass(), newValueMap)); |
| } |
| |
| /** |
| * Puts value with key in the testDataMap. The value map is thereby |
| * automatically identified by the implementing class. |
| * |
| * @param key key to store value under |
| * @param value value to store |
| */ |
| protected static void putTestDataValue(String key, String value) { |
| Map<String, String> entityTestData = testDataMap.getOrElse(getContextClass(), HashMap.empty()); |
| |
| String valueWithSuffix = value; |
| |
| // randomize name to allow failure runs not to require to reset the |
| // database in case the name of the entity must be unique |
| // do not append suffix if name is randomly generated |
| if (key.equals(TESTDATA_ENTITY_NAME) && !value.equals(TESTDATA_RANDOM_DATA) |
| && (entityTestData.get(TESTDATA_ENTITY_NAME).isEmpty() |
| || !entityTestData.get(TESTDATA_ENTITY_NAME).get().equals(TESTDATA_RANDOM_DATA))) { |
| // append suffix if it was not already appended or an already suffixed value was |
| // used for a new one (e.g: TplAttr.name and CatAttr.name) |
| if (!value.endsWith(RANDOM_ENTITY_NAME_SUFFIX)) { |
| valueWithSuffix = value + RANDOM_ENTITY_NAME_SUFFIX; |
| } |
| } |
| |
| entityTestData = entityTestData.put(key, valueWithSuffix); |
| |
| testDataMap = testDataMap.put(getContextClass(), entityTestData); |
| } |
| |
| /** |
| * Gets the context class set by a test implementation used to store context |
| * aware test data |
| * |
| * @return the context class of the test implementation |
| */ |
| protected static Class<?> getContextClass() { |
| assertThat(contextClass, is(notNullValue())); |
| return contextClass; |
| } |
| |
| /** |
| * Sets the context class used to store context aware test data. This method |
| * must be called by any test implementation before using |
| * {@link getTestDataValue} or {@link putTestDataValue} |
| * |
| * @param clazz the context class set by a test implementation |
| */ |
| protected static void setContextClass(Class<?> clazz) { |
| contextClass = clazz; |
| testsToSkip = testsToSkip.put(clazz, HashSet.empty()); |
| LOGGER = LoggerFactory.getLogger(clazz); |
| } |
| |
| /** |
| * Set the test with the given {@link TestType} to be skipped |
| * |
| * @param testType the test to skip |
| */ |
| protected static void skipTest(TestType test) { |
| testsToSkip.get(getContextClass()).map(tests -> tests.add(test)) |
| .map(newTests -> testsToSkip = testsToSkip.put(getContextClass(), newTests)); |
| } |
| |
| /** |
| * Sets the option findByName to either true or false. If it's set to true, the |
| * URI for find() is constructed with the name rather than with the id of the |
| * entity as the PATH_PARAM |
| * |
| * @param findByName if find() should use the name instead of the id of the |
| * entity |
| */ |
| protected static void setFindByName(boolean findByNameValue) { |
| findByName = findByName.put(getContextClass(), findByNameValue); |
| } |
| |
| /** |
| * Gets the logger |
| * |
| * @return logger configured to current context class |
| */ |
| protected static Logger getLogger() { |
| return LOGGER; |
| } |
| } |