blob: af5510d181ef07e6ba7bdff7da0128366ea207cf [file] [log] [blame]
/********************************************************************************
* 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;
}
}