TSK-1856: duplicating the test-api into a dedicated module
This commit is contained in:
parent
7821c12338
commit
54f01f8927
|
@ -247,6 +247,7 @@ jobs:
|
|||
- taskana-core
|
||||
- taskana-cdi
|
||||
- taskana-cdi-example
|
||||
- taskana-test-api
|
||||
- taskana-spring
|
||||
- taskana-spring-example
|
||||
- taskana-spi-routing-dmn-router
|
||||
|
@ -263,6 +264,10 @@ jobs:
|
|||
database: POSTGRES
|
||||
- module: taskana-core
|
||||
database: DB2
|
||||
- module: taskana-test-api
|
||||
database: POSTGRES
|
||||
- module: taskana-test-api
|
||||
database: DB2
|
||||
- module: taskana-rest-spring-example-boot
|
||||
database: DB2
|
||||
- module: taskana-rest-spring-example-wildfly
|
||||
|
@ -352,7 +357,7 @@ jobs:
|
|||
-pl :taskana-parent,\
|
||||
:taskana-common-parent,:taskana-common-logging,:taskana-common,:taskana-common-security,\
|
||||
:taskana-common-data,:taskana-common-test,\
|
||||
:taskana-lib-parent,:taskana-core,:taskana-cdi,:taskana-spring,\
|
||||
:taskana-lib-parent,:taskana-core,:taskana-cdi,:taskana-spring, :taskana-test-api\
|
||||
:taskana-rest-parent,:taskana-web,:taskana-rest-spring,\
|
||||
:taskana-history-parent,:taskana-simplehistory-provider,:taskana-simplehistory-rest-spring,:taskana-loghistory-provider,\
|
||||
:taskana-routing-parent,:taskana-spi-routing-dmn-router,:taskana-routing-rest
|
||||
|
|
|
@ -59,6 +59,11 @@
|
|||
<artifactId>taskana-spring</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>pro.taskana</groupId>
|
||||
<artifactId>taskana-test-api</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- all rest dependencies -->
|
||||
<dependency>
|
||||
|
|
|
@ -22,5 +22,6 @@
|
|||
<module>taskana-spring</module>
|
||||
<module>taskana-cdi-example</module>
|
||||
<module>taskana-spring-example</module>
|
||||
<module>taskana-test-api</module>
|
||||
</modules>
|
||||
</project>
|
||||
|
|
|
@ -0,0 +1,99 @@
|
|||
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>taskana-test-api</artifactId>
|
||||
|
||||
<name>${project.groupId}:${project.artifactId}</name>
|
||||
<description>The taskana test-api to include in your project.</description>
|
||||
<parent>
|
||||
<groupId>pro.taskana</groupId>
|
||||
<artifactId>taskana-lib-parent</artifactId>
|
||||
<version>5.1.1-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>pro.taskana</groupId>
|
||||
<artifactId>taskana-common-logging</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>pro.taskana</groupId>
|
||||
<artifactId>taskana-common</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>pro.taskana</groupId>
|
||||
<artifactId>taskana-core</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mockito</groupId>
|
||||
<artifactId>mockito-inline</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.testcontainers</groupId>
|
||||
<artifactId>db2</artifactId>
|
||||
<version>${version.testcontainers}</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.testcontainers</groupId>
|
||||
<artifactId>postgresql</artifactId>
|
||||
<version>${version.testcontainers}</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<!-- test dependencies -->
|
||||
<dependency>
|
||||
<groupId>org.assertj</groupId>
|
||||
<artifactId>assertj-core</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-simple</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.h2database</groupId>
|
||||
<artifactId>h2</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.postgresql</groupId>
|
||||
<artifactId>postgresql</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.ibm.db2.jcc</groupId>
|
||||
<artifactId>db2jcc4</artifactId>
|
||||
<version>${version.db2}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<repositories>
|
||||
<!-- this repository is needed to fetch com.ibm.db2.jcc -->
|
||||
<repository>
|
||||
<id>novatec public</id>
|
||||
<name>novatec-repository</name>
|
||||
<url>https://repository.novatec-gmbh.de/content/repositories/novatec/</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
</project>
|
|
@ -0,0 +1,8 @@
|
|||
package org.junit.rules;
|
||||
|
||||
// Testcontainers currently requires junit4 as a runtime dependency.
|
||||
// Because we use junit5 we have to use this workaround to "simulate" the classes testcontainers
|
||||
// requires in the classpath. They are not used unless a junit4 runtime is used.
|
||||
// See: https://github.com/testcontainers/testcontainers-java/issues/970#issuecomment-625044008
|
||||
@SuppressWarnings("unused")
|
||||
public interface TestRule {}
|
|
@ -0,0 +1,8 @@
|
|||
package org.junit.runners.model;
|
||||
|
||||
// Testcontainers currently requires junit4 as a runtime dependency.
|
||||
// Because we use junit5 we have to use this workaround to "simulate" the classes testcontainers
|
||||
// requires in the classpath. They are not used unless a junit4 runtime is used.
|
||||
// See: https://github.com/testcontainers/testcontainers-java/issues/970#issuecomment-625044008
|
||||
@SuppressWarnings("unused")
|
||||
public interface Statement {}
|
|
@ -0,0 +1,10 @@
|
|||
package pro.taskana.testapi;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.TYPE)
|
||||
public @interface CleanTaskanaContext {}
|
|
@ -0,0 +1,71 @@
|
|||
package pro.taskana.testapi;
|
||||
|
||||
import static java.time.temporal.ChronoUnit.SECONDS;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.Optional;
|
||||
import javax.sql.DataSource;
|
||||
import org.apache.ibatis.datasource.pooled.PooledDataSource;
|
||||
import org.testcontainers.containers.Db2Container;
|
||||
import org.testcontainers.containers.JdbcDatabaseContainer;
|
||||
import org.testcontainers.containers.PostgreSQLContainer;
|
||||
import org.testcontainers.containers.wait.strategy.LogMessageWaitStrategy;
|
||||
import org.testcontainers.utility.DockerImageName;
|
||||
|
||||
import pro.taskana.common.internal.configuration.DB;
|
||||
|
||||
public class DockerContainerCreator {
|
||||
|
||||
private DockerContainerCreator() {
|
||||
throw new IllegalStateException("Utility class");
|
||||
}
|
||||
|
||||
public static Optional<JdbcDatabaseContainer<?>> createDockerContainer(DB db) {
|
||||
switch (db) {
|
||||
case DB2:
|
||||
return Optional.of(
|
||||
new Db2Container(
|
||||
DockerImageName.parse("taskana/db2:11.5")
|
||||
.asCompatibleSubstituteFor("ibmcom/db2"))
|
||||
.waitingFor(
|
||||
new LogMessageWaitStrategy()
|
||||
.withRegEx(".*DB2START processing was successful.*")
|
||||
.withStartupTimeout(Duration.of(60, SECONDS)))
|
||||
.withUsername("db2inst1")
|
||||
.withPassword("db2inst1-pwd")
|
||||
.withDatabaseName("TSKDB"));
|
||||
case POSTGRES:
|
||||
return Optional.of(
|
||||
new PostgreSQLContainer<>(DockerImageName.parse("postgres:10"))
|
||||
.withUsername("postgres")
|
||||
.withPassword("postgres")
|
||||
.withDatabaseName("postgres")
|
||||
.withCommand(
|
||||
"/bin/sh",
|
||||
"-c",
|
||||
"localedef -i de_DE -c -f UTF-8 -A /usr/share/locale/locale.alias de_DE.UTF-8 "
|
||||
+ "&& export LANG=de_DE.UTF-8 "
|
||||
+ "&& ./docker-entrypoint.sh postgres -c fsync=off")
|
||||
.waitingFor(
|
||||
new LogMessageWaitStrategy()
|
||||
.withRegEx(".*Datenbanksystem ist bereit, um Verbindungen anzunehmen.*\\s")
|
||||
.withTimes(2)
|
||||
.withStartupTimeout(Duration.of(60, SECONDS))));
|
||||
default:
|
||||
return Optional.empty();
|
||||
}
|
||||
}
|
||||
|
||||
public static DataSource createDataSource(JdbcDatabaseContainer<?> container) {
|
||||
PooledDataSource ds =
|
||||
new PooledDataSource(
|
||||
Thread.currentThread().getContextClassLoader(),
|
||||
container.getDriverClassName(),
|
||||
container.getJdbcUrl(),
|
||||
container.getUsername(),
|
||||
container.getPassword());
|
||||
ds.setPoolTimeToWait(50);
|
||||
ds.forceCloseAll(); // otherwise, the MyBatis pool is not initialized correctly
|
||||
return ds;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
package pro.taskana.testapi;
|
||||
|
||||
import pro.taskana.TaskanaEngineConfiguration;
|
||||
|
||||
public interface TaskanaEngineConfigurationModifier {
|
||||
|
||||
void modify(TaskanaEngineConfiguration taskanaEngineConfiguration);
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
package pro.taskana.testapi;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import org.apache.ibatis.session.SqlSession;
|
||||
|
||||
import pro.taskana.common.api.TaskanaEngine;
|
||||
import pro.taskana.common.internal.InternalTaskanaEngine;
|
||||
import pro.taskana.common.internal.TaskanaEngineImpl;
|
||||
|
||||
/** Utility class to enable unit tests to access mappers directly. */
|
||||
public class TaskanaEngineProxy {
|
||||
|
||||
private final InternalTaskanaEngine engine;
|
||||
|
||||
public TaskanaEngineProxy(TaskanaEngine taskanaEngine) throws Exception {
|
||||
Field internal = TaskanaEngineImpl.class.getDeclaredField("internalTaskanaEngineImpl");
|
||||
internal.setAccessible(true);
|
||||
engine = (InternalTaskanaEngine) internal.get(taskanaEngine);
|
||||
}
|
||||
|
||||
public InternalTaskanaEngine getEngine() {
|
||||
return engine;
|
||||
}
|
||||
|
||||
public SqlSession getSqlSession() {
|
||||
return engine.getSqlSession();
|
||||
}
|
||||
|
||||
public void openConnection() {
|
||||
engine.openConnection();
|
||||
}
|
||||
|
||||
public void returnConnection() {
|
||||
engine.returnConnection();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
package pro.taskana.testapi;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.FIELD)
|
||||
public @interface TaskanaInject {}
|
|
@ -0,0 +1,26 @@
|
|||
package pro.taskana.testapi;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
import org.junit.jupiter.api.TestInstance;
|
||||
import org.junit.jupiter.api.TestInstance.Lifecycle;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
|
||||
import pro.taskana.testapi.extensions.TaskanaDependencyInjectionExtension;
|
||||
import pro.taskana.testapi.extensions.TaskanaInitializationExtension;
|
||||
import pro.taskana.testapi.extensions.TestContainerExtension;
|
||||
import pro.taskana.testapi.security.JaasExtension;
|
||||
|
||||
@ExtendWith({
|
||||
// ORDER IS IMPORTANT!
|
||||
JaasExtension.class,
|
||||
TestContainerExtension.class,
|
||||
TaskanaInitializationExtension.class,
|
||||
TaskanaDependencyInjectionExtension.class,
|
||||
})
|
||||
@TestInstance(Lifecycle.PER_CLASS)
|
||||
@Target(ElementType.TYPE)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface TaskanaIntegrationTest {}
|
|
@ -0,0 +1,26 @@
|
|||
package pro.taskana.testapi;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Repeatable;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import pro.taskana.testapi.WithServiceProvider.WithServiceProviders;
|
||||
|
||||
@Target(ElementType.TYPE)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Repeatable(WithServiceProviders.class)
|
||||
public @interface WithServiceProvider {
|
||||
|
||||
Class<?> serviceProviderInterface();
|
||||
|
||||
Class<?>[] serviceProviders();
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.TYPE)
|
||||
@interface WithServiceProviders {
|
||||
|
||||
WithServiceProvider[] value();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,64 @@
|
|||
package pro.taskana.testapi.extensions;
|
||||
|
||||
import static org.junit.platform.commons.support.AnnotationSupport.findAnnotatedFields;
|
||||
import static pro.taskana.testapi.util.ExtensionCommunicator.getClassLevelStore;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Map;
|
||||
import org.junit.jupiter.api.extension.ExtensionContext;
|
||||
import org.junit.jupiter.api.extension.ParameterContext;
|
||||
import org.junit.jupiter.api.extension.ParameterResolutionException;
|
||||
import org.junit.jupiter.api.extension.ParameterResolver;
|
||||
import org.junit.jupiter.api.extension.TestInstancePostProcessor;
|
||||
import org.junit.platform.commons.JUnitException;
|
||||
|
||||
import pro.taskana.testapi.TaskanaInject;
|
||||
|
||||
public class TaskanaDependencyInjectionExtension
|
||||
implements ParameterResolver, TestInstancePostProcessor {
|
||||
|
||||
@Override
|
||||
public boolean supportsParameter(
|
||||
ParameterContext parameterContext, ExtensionContext extensionContext)
|
||||
throws ParameterResolutionException {
|
||||
Map<Class<?>, Object> instanceByClass = getTaskanaEntityMap(extensionContext);
|
||||
return instanceByClass != null
|
||||
&& instanceByClass.containsKey(parameterContext.getParameter().getType());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object resolveParameter(
|
||||
ParameterContext parameterContext, ExtensionContext extensionContext)
|
||||
throws ParameterResolutionException {
|
||||
return getTaskanaEntityMap(extensionContext).get(parameterContext.getParameter().getType());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postProcessTestInstance(Object testInstance, ExtensionContext context)
|
||||
throws Exception {
|
||||
Map<Class<?>, Object> instanceByClass = getTaskanaEntityMap(context);
|
||||
if (instanceByClass == null) {
|
||||
throw new JUnitException("Something went wrong! Could not find TASKANA entity Map in store.");
|
||||
}
|
||||
|
||||
for (Field field : findAnnotatedFields(testInstance.getClass(), TaskanaInject.class)) {
|
||||
Object toInject = instanceByClass.get(field.getType());
|
||||
if (toInject != null) {
|
||||
field.setAccessible(true);
|
||||
field.set(testInstance, toInject);
|
||||
} else {
|
||||
throw new JUnitException(
|
||||
String.format(
|
||||
"Cannot inject field '%s'. " + "Type '%s' is not an injectable TASKANA type",
|
||||
field.getName(), field.getType()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private static Map<Class<?>, Object> getTaskanaEntityMap(ExtensionContext extensionContext) {
|
||||
return (Map<Class<?>, Object>)
|
||||
getClassLevelStore(extensionContext)
|
||||
.get(TaskanaInitializationExtension.STORE_TASKANA_ENTITY_MAP);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,126 @@
|
|||
package pro.taskana.testapi.extensions;
|
||||
|
||||
import static org.junit.platform.commons.support.AnnotationSupport.isAnnotated;
|
||||
import static pro.taskana.testapi.util.ExtensionCommunicator.getClassLevelStore;
|
||||
import static pro.taskana.testapi.util.ExtensionCommunicator.isTopLevelClass;
|
||||
|
||||
import java.util.Map;
|
||||
import javax.sql.DataSource;
|
||||
import org.apache.ibatis.session.SqlSession;
|
||||
import org.junit.jupiter.api.extension.ExtensionContext;
|
||||
import org.junit.jupiter.api.extension.ExtensionContext.Store;
|
||||
import org.junit.jupiter.api.extension.TestInstancePostProcessor;
|
||||
import org.junit.platform.commons.JUnitException;
|
||||
import org.mockito.MockedStatic;
|
||||
import org.mockito.Mockito;
|
||||
|
||||
import pro.taskana.TaskanaEngineConfiguration;
|
||||
import pro.taskana.classification.api.ClassificationService;
|
||||
import pro.taskana.classification.internal.ClassificationServiceImpl;
|
||||
import pro.taskana.common.api.ConfigurationService;
|
||||
import pro.taskana.common.api.JobService;
|
||||
import pro.taskana.common.api.TaskanaEngine;
|
||||
import pro.taskana.common.api.TaskanaEngine.ConnectionManagementMode;
|
||||
import pro.taskana.common.api.WorkingDaysToDaysConverter;
|
||||
import pro.taskana.common.api.security.CurrentUserContext;
|
||||
import pro.taskana.common.internal.ConfigurationMapper;
|
||||
import pro.taskana.common.internal.ConfigurationServiceImpl;
|
||||
import pro.taskana.common.internal.InternalTaskanaEngine;
|
||||
import pro.taskana.common.internal.JobServiceImpl;
|
||||
import pro.taskana.common.internal.TaskanaEngineImpl;
|
||||
import pro.taskana.common.internal.security.CurrentUserContextImpl;
|
||||
import pro.taskana.common.internal.util.SpiLoader;
|
||||
import pro.taskana.monitor.api.MonitorService;
|
||||
import pro.taskana.monitor.internal.MonitorServiceImpl;
|
||||
import pro.taskana.task.api.TaskService;
|
||||
import pro.taskana.task.internal.TaskServiceImpl;
|
||||
import pro.taskana.testapi.CleanTaskanaContext;
|
||||
import pro.taskana.testapi.TaskanaEngineConfigurationModifier;
|
||||
import pro.taskana.testapi.TaskanaEngineProxy;
|
||||
import pro.taskana.testapi.WithServiceProvider;
|
||||
import pro.taskana.testapi.util.ServiceProviderExtractor;
|
||||
import pro.taskana.workbasket.api.WorkbasketService;
|
||||
import pro.taskana.workbasket.internal.WorkbasketServiceImpl;
|
||||
|
||||
public class TaskanaInitializationExtension implements TestInstancePostProcessor {
|
||||
|
||||
public static final String STORE_TASKANA_ENTITY_MAP = "taskanaEntityMap";
|
||||
|
||||
@Override
|
||||
public void postProcessTestInstance(Object testInstance, ExtensionContext context)
|
||||
throws Exception {
|
||||
Class<?> testClass = testInstance.getClass();
|
||||
if (isTopLevelClass(testClass)
|
||||
|| isAnnotated(testClass, CleanTaskanaContext.class)
|
||||
|| isAnnotated(testClass, WithServiceProvider.class)
|
||||
|| testInstance instanceof TaskanaEngineConfigurationModifier) {
|
||||
Store store = getClassLevelStore(context);
|
||||
TaskanaEngineConfiguration taskanaEngineConfiguration =
|
||||
createDefaultTaskanaEngineConfiguration(store);
|
||||
|
||||
if (testInstance instanceof TaskanaEngineConfigurationModifier) {
|
||||
TaskanaEngineConfigurationModifier modifier =
|
||||
(TaskanaEngineConfigurationModifier) testInstance;
|
||||
modifier.modify(taskanaEngineConfiguration);
|
||||
}
|
||||
|
||||
TaskanaEngine taskanaEngine;
|
||||
try (MockedStatic<SpiLoader> staticMock = Mockito.mockStatic(SpiLoader.class)) {
|
||||
ServiceProviderExtractor.extractServiceProviders(testClass)
|
||||
.forEach(
|
||||
(spi, serviceProviders) ->
|
||||
staticMock.when(() -> SpiLoader.load(spi)).thenReturn(serviceProviders));
|
||||
taskanaEngine =
|
||||
taskanaEngineConfiguration.buildTaskanaEngine(ConnectionManagementMode.AUTOCOMMIT);
|
||||
}
|
||||
|
||||
store.put(STORE_TASKANA_ENTITY_MAP, generateTaskanaEntityMap(taskanaEngine));
|
||||
}
|
||||
}
|
||||
|
||||
private static TaskanaEngineConfiguration createDefaultTaskanaEngineConfiguration(Store store) {
|
||||
String schemaName = store.get(TestContainerExtension.STORE_SCHEMA_NAME, String.class);
|
||||
if (schemaName == null) {
|
||||
throw new JUnitException("Expected schemaName to be defined in store, but it's not.");
|
||||
}
|
||||
DataSource dataSource = store.get(TestContainerExtension.STORE_DATA_SOURCE, DataSource.class);
|
||||
if (dataSource == null) {
|
||||
throw new JUnitException("Expected dataSource to be defined in store, but it's not.");
|
||||
}
|
||||
|
||||
return new TaskanaEngineConfiguration(dataSource, false, schemaName);
|
||||
}
|
||||
|
||||
private static Map<Class<?>, Object> generateTaskanaEntityMap(TaskanaEngine taskanaEngine)
|
||||
throws Exception {
|
||||
TaskService taskService = taskanaEngine.getTaskService();
|
||||
TaskanaEngineProxy taskanaEngineProxy = new TaskanaEngineProxy(taskanaEngine);
|
||||
MonitorService monitorService = taskanaEngine.getMonitorService();
|
||||
WorkbasketService workbasketService = taskanaEngine.getWorkbasketService();
|
||||
ClassificationService classificationService = taskanaEngine.getClassificationService();
|
||||
JobService jobService = taskanaEngine.getJobService();
|
||||
CurrentUserContext currentUserContext = taskanaEngine.getCurrentUserContext();
|
||||
SqlSession sqlSession = taskanaEngineProxy.getSqlSession();
|
||||
return Map.ofEntries(
|
||||
Map.entry(TaskanaEngineConfiguration.class, taskanaEngine.getConfiguration()),
|
||||
Map.entry(TaskanaEngineImpl.class, taskanaEngine),
|
||||
Map.entry(TaskanaEngine.class, taskanaEngine),
|
||||
Map.entry(InternalTaskanaEngine.class, taskanaEngineProxy.getEngine()),
|
||||
Map.entry(TaskService.class, taskService),
|
||||
Map.entry(TaskServiceImpl.class, taskService),
|
||||
Map.entry(MonitorService.class, monitorService),
|
||||
Map.entry(MonitorServiceImpl.class, monitorService),
|
||||
Map.entry(WorkbasketService.class, workbasketService),
|
||||
Map.entry(WorkbasketServiceImpl.class, workbasketService),
|
||||
Map.entry(ClassificationService.class, classificationService),
|
||||
Map.entry(ClassificationServiceImpl.class, classificationService),
|
||||
Map.entry(ConfigurationService.class, taskanaEngine.getConfigurationService()),
|
||||
Map.entry(ConfigurationServiceImpl.class, taskanaEngine.getConfigurationService()),
|
||||
Map.entry(JobService.class, jobService),
|
||||
Map.entry(JobServiceImpl.class, jobService),
|
||||
Map.entry(CurrentUserContext.class, currentUserContext),
|
||||
Map.entry(CurrentUserContextImpl.class, currentUserContext),
|
||||
Map.entry(WorkingDaysToDaysConverter.class, taskanaEngine.getWorkingDaysToDaysConverter()),
|
||||
Map.entry(ConfigurationMapper.class, sqlSession.getMapper(ConfigurationMapper.class)));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,117 @@
|
|||
package pro.taskana.testapi.extensions;
|
||||
|
||||
import static org.junit.platform.commons.support.AnnotationSupport.isAnnotated;
|
||||
import static pro.taskana.testapi.DockerContainerCreator.createDataSource;
|
||||
import static pro.taskana.testapi.DockerContainerCreator.createDockerContainer;
|
||||
import static pro.taskana.testapi.util.ExtensionCommunicator.getClassLevelStore;
|
||||
import static pro.taskana.testapi.util.ExtensionCommunicator.isTopLevelClass;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
import javax.sql.DataSource;
|
||||
import org.apache.ibatis.datasource.pooled.PooledDataSource;
|
||||
import org.junit.jupiter.api.extension.AfterAllCallback;
|
||||
import org.junit.jupiter.api.extension.ExtensionContext;
|
||||
import org.junit.jupiter.api.extension.ExtensionContext.Store;
|
||||
import org.junit.jupiter.api.extension.InvocationInterceptor;
|
||||
import org.junit.jupiter.api.extension.ReflectiveInvocationContext;
|
||||
import org.junit.platform.commons.support.AnnotationSupport;
|
||||
import org.testcontainers.containers.GenericContainer;
|
||||
import org.testcontainers.containers.JdbcDatabaseContainer;
|
||||
|
||||
import pro.taskana.common.internal.configuration.DB;
|
||||
import pro.taskana.testapi.CleanTaskanaContext;
|
||||
import pro.taskana.testapi.TaskanaEngineConfigurationModifier;
|
||||
import pro.taskana.testapi.WithServiceProvider;
|
||||
|
||||
public class TestContainerExtension implements AfterAllCallback, InvocationInterceptor {
|
||||
|
||||
public static final String STORE_DATA_SOURCE = "datasource";
|
||||
public static final String STORE_CONTAINER = "container";
|
||||
public static final String STORE_SCHEMA_NAME = "schemaName";
|
||||
|
||||
@Override
|
||||
public <T> T interceptTestClassConstructor(
|
||||
Invocation<T> invocation,
|
||||
ReflectiveInvocationContext<Constructor<T>> invocationContext,
|
||||
ExtensionContext extensionContext)
|
||||
throws Throwable {
|
||||
Class<?> testClass = extensionContext.getRequiredTestClass();
|
||||
if (isTopLevelClass(testClass) || isAnnotated(testClass, CleanTaskanaContext.class)) {
|
||||
Store store = getClassLevelStore(extensionContext);
|
||||
DB db = retrieveDatabaseFromEnv();
|
||||
store.put(STORE_SCHEMA_NAME, determineSchemaName(db));
|
||||
|
||||
createDockerContainer(db)
|
||||
.ifPresentOrElse(
|
||||
container -> {
|
||||
container.start();
|
||||
store.put(STORE_DATA_SOURCE, createDataSource(container));
|
||||
store.put(STORE_CONTAINER, container);
|
||||
},
|
||||
() -> store.put(STORE_DATA_SOURCE, createDataSourceForH2()));
|
||||
|
||||
} else if (TaskanaEngineConfigurationModifier.class.isAssignableFrom(testClass)
|
||||
|| isAnnotated(testClass, WithServiceProvider.class)) {
|
||||
// since the implementation of TaskanaEngineConfigurationModifier implies the generation of a
|
||||
// new TaskanaEngine, we have to copy the schema name and datasource from the enclosing class'
|
||||
// store to the testClass store.
|
||||
// This allows the following extensions to generate a new TaskanaEngine for the testClass.
|
||||
Store parentStore = getClassLevelStore(extensionContext, testClass.getEnclosingClass());
|
||||
Store store = getClassLevelStore(extensionContext);
|
||||
copyValue(TestContainerExtension.STORE_SCHEMA_NAME, parentStore, store);
|
||||
copyValue(TestContainerExtension.STORE_DATA_SOURCE, parentStore, store);
|
||||
}
|
||||
return invocation.proceed();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterAll(ExtensionContext context) {
|
||||
Class<?> testClass = context.getRequiredTestClass();
|
||||
if (isTopLevelClass(testClass)
|
||||
|| AnnotationSupport.isAnnotated(testClass, CleanTaskanaContext.class)) {
|
||||
Optional.ofNullable(getClassLevelStore(context).get(STORE_CONTAINER))
|
||||
.map(JdbcDatabaseContainer.class::cast)
|
||||
.ifPresent(GenericContainer::stop);
|
||||
}
|
||||
}
|
||||
|
||||
private static void copyValue(String key, Store source, Store destination) {
|
||||
Object value = source.get(key);
|
||||
destination.put(key, value);
|
||||
}
|
||||
|
||||
private static String determineSchemaName(DB db) {
|
||||
return db == DB.POSTGRES ? "taskana" : "TASKANA";
|
||||
}
|
||||
|
||||
private static DB retrieveDatabaseFromEnv() {
|
||||
String property = System.getenv("DB");
|
||||
DB db;
|
||||
try {
|
||||
db = DB.valueOf(property);
|
||||
} catch (Exception ex) {
|
||||
db = DB.H2;
|
||||
}
|
||||
return db;
|
||||
}
|
||||
|
||||
private static DataSource createDataSourceForH2() {
|
||||
PooledDataSource ds =
|
||||
new PooledDataSource(
|
||||
Thread.currentThread().getContextClassLoader(),
|
||||
"org.h2.Driver",
|
||||
"jdbc:h2:mem:"
|
||||
+ UUID.randomUUID()
|
||||
+ ";LOCK_MODE=0;"
|
||||
+ "INIT=CREATE SCHEMA IF NOT EXISTS TASKANA\\;"
|
||||
+ "SET COLLATION DEFAULT_de_DE ",
|
||||
"sa",
|
||||
"sa");
|
||||
ds.setPoolTimeToWait(50);
|
||||
ds.forceCloseAll(); // otherwise, the MyBatis pool is not initialized correctly
|
||||
|
||||
return ds;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,328 @@
|
|||
package pro.taskana.testapi.security;
|
||||
|
||||
import static org.junit.platform.commons.support.AnnotationSupport.isAnnotated;
|
||||
import static pro.taskana.common.internal.util.CheckedFunction.wrapExceptFor;
|
||||
|
||||
import java.lang.reflect.AnnotatedElement;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Method;
|
||||
import java.security.Principal;
|
||||
import java.security.PrivilegedAction;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
import java.util.stream.StreamSupport;
|
||||
import javax.security.auth.Subject;
|
||||
import org.junit.jupiter.api.DynamicContainer;
|
||||
import org.junit.jupiter.api.DynamicNode;
|
||||
import org.junit.jupiter.api.extension.DynamicTestInvocationContext;
|
||||
import org.junit.jupiter.api.extension.Extension;
|
||||
import org.junit.jupiter.api.extension.ExtensionContext;
|
||||
import org.junit.jupiter.api.extension.ExtensionContext.Namespace;
|
||||
import org.junit.jupiter.api.extension.ExtensionContext.Store;
|
||||
import org.junit.jupiter.api.extension.InvocationInterceptor;
|
||||
import org.junit.jupiter.api.extension.ParameterContext;
|
||||
import org.junit.jupiter.api.extension.ParameterResolver;
|
||||
import org.junit.jupiter.api.extension.ReflectiveInvocationContext;
|
||||
import org.junit.jupiter.api.extension.TestTemplateInvocationContext;
|
||||
import org.junit.jupiter.api.extension.TestTemplateInvocationContextProvider;
|
||||
import org.junit.platform.commons.JUnitException;
|
||||
import org.junit.platform.commons.support.AnnotationSupport;
|
||||
import org.opentest4j.TestAbortedException;
|
||||
|
||||
import pro.taskana.common.api.exceptions.SystemException;
|
||||
import pro.taskana.common.api.security.GroupPrincipal;
|
||||
import pro.taskana.common.api.security.UserPrincipal;
|
||||
import pro.taskana.testapi.security.WithAccessId.WithAccessIds;
|
||||
|
||||
/** Runner for integration tests that enables JAAS subject. */
|
||||
public class JaasExtension implements InvocationInterceptor, TestTemplateInvocationContextProvider {
|
||||
|
||||
private static final String ACCESS_IDS_STORE_KEY = "accessIds";
|
||||
|
||||
// region InvocationInterceptor
|
||||
|
||||
@Override
|
||||
public <T> T interceptTestClassConstructor(
|
||||
Invocation<T> invocation,
|
||||
ReflectiveInvocationContext<Constructor<T>> invocationContext,
|
||||
ExtensionContext extensionContext) {
|
||||
return extractAccessIdAndPerformInvocation(invocation, invocationContext.getExecutable());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void interceptBeforeAllMethod(
|
||||
Invocation<Void> invocation,
|
||||
ReflectiveInvocationContext<Method> invocationContext,
|
||||
ExtensionContext extensionContext) {
|
||||
extractAccessIdAndPerformInvocation(invocation, invocationContext.getExecutable());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void interceptBeforeEachMethod(
|
||||
Invocation<Void> invocation,
|
||||
ReflectiveInvocationContext<Method> invocationContext,
|
||||
ExtensionContext extensionContext) {
|
||||
extractAccessIdAndPerformInvocation(invocation, invocationContext.getExecutable());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void interceptTestMethod(
|
||||
Invocation<Void> invocation,
|
||||
ReflectiveInvocationContext<Method> invocationContext,
|
||||
ExtensionContext extensionContext) {
|
||||
if (isAnnotated(invocationContext.getExecutable(), WithAccessIds.class)) {
|
||||
throw new JUnitException("Please use @TestTemplate instead of @Test for multiple accessIds");
|
||||
}
|
||||
extractAccessIdAndPerformInvocation(invocation, invocationContext.getExecutable());
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> T interceptTestFactoryMethod(
|
||||
Invocation<T> invocation,
|
||||
ReflectiveInvocationContext<Method> invocationContext,
|
||||
ExtensionContext extensionContext) {
|
||||
WithAccessIds annotation = invocationContext.getExecutable().getAnnotation(WithAccessIds.class);
|
||||
if (annotation != null) {
|
||||
// our goal is to run each test returned from the test factory X times. X is the amount of
|
||||
// WithAccessId annotations. In order to achieve this we are wrapping the result from the
|
||||
// factory (the returning tests) in a dynamicContainer for each accessId. Since we don't know
|
||||
// what the factory will return we have to check for every possible return type. All possible
|
||||
// return types can be found here:
|
||||
// https://junit.org/junit5/docs/current/user-guide/#writing-tests-dynamic-tests
|
||||
// After checking each return type we abuse the return type of T and hardly change it to
|
||||
// Stream<DynamicContainer> no matter what the factory returns. This return type is allowed
|
||||
// per definition (See link above), but is not the type T. Hence we have an unchecked cast at
|
||||
// the end to keep the compiler happy...
|
||||
|
||||
// we are using the first annotation to run the factory method with.
|
||||
T factoryResult = performInvocationWithAccessId(invocation, annotation.value()[0]);
|
||||
|
||||
Iterable<DynamicNode> newChildrenForDynamicContainer;
|
||||
// TestFactory must have one of the following return types. See link above for further details
|
||||
if (factoryResult instanceof DynamicNode) {
|
||||
newChildrenForDynamicContainer = Collections.singleton((DynamicNode) factoryResult);
|
||||
} else if (factoryResult instanceof Stream) {
|
||||
Stream<DynamicNode> nodes = (Stream<DynamicNode>) factoryResult;
|
||||
newChildrenForDynamicContainer = nodes.collect(Collectors.toList());
|
||||
} else if (factoryResult instanceof Iterable) {
|
||||
newChildrenForDynamicContainer = (Iterable<DynamicNode>) factoryResult;
|
||||
} else if (factoryResult instanceof Iterator) {
|
||||
newChildrenForDynamicContainer = () -> (Iterator<DynamicNode>) factoryResult;
|
||||
} else if (factoryResult instanceof DynamicNode[]) {
|
||||
newChildrenForDynamicContainer = Arrays.asList((DynamicNode[]) factoryResult);
|
||||
} else {
|
||||
throw new SystemException(
|
||||
String.format(
|
||||
"Testfactory '%s' did not return a proper type",
|
||||
invocationContext.getExecutable().getName()));
|
||||
}
|
||||
|
||||
// Currently, a DynamicContainer has children from this type: Stream<DynamicNode>
|
||||
// Because of this the children can only be extracted once (Streams can only be operated
|
||||
// once). This is obviously not ok since we want to execute each node X times. So we have to
|
||||
// manually insert all children recursively to extract them X times...
|
||||
Map<String, List<DynamicNode>> childrenMap = new HashMap<>();
|
||||
persistDynamicContainerChildren(newChildrenForDynamicContainer, childrenMap);
|
||||
|
||||
Function<WithAccessId, DynamicContainer> wrapTestsInDynamicContainer =
|
||||
accessId ->
|
||||
DynamicContainer.dynamicContainer(
|
||||
getDisplayNameForAccessId(accessId),
|
||||
StreamSupport.stream(newChildrenForDynamicContainer.spliterator(), false)
|
||||
.map(x -> duplicateDynamicNode(x, childrenMap)));
|
||||
|
||||
Store store = getMethodLevelStore(extensionContext);
|
||||
return (T)
|
||||
Stream.of(annotation.value())
|
||||
.peek(a -> store.put(ACCESS_IDS_STORE_KEY, a))
|
||||
.map(wrapTestsInDynamicContainer);
|
||||
}
|
||||
|
||||
return extractAccessIdAndPerformInvocation(invocation, invocationContext.getExecutable());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void interceptTestTemplateMethod(
|
||||
Invocation<Void> invocation,
|
||||
ReflectiveInvocationContext<Method> invocationContext,
|
||||
ExtensionContext extensionContext) {
|
||||
WithAccessId accessId =
|
||||
getMethodLevelStore(extensionContext).get(ACCESS_IDS_STORE_KEY, WithAccessId.class);
|
||||
performInvocationWithAccessId(invocation, accessId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void interceptDynamicTest(
|
||||
Invocation<Void> invocation,
|
||||
DynamicTestInvocationContext invocationContext,
|
||||
ExtensionContext extensionContext) {
|
||||
ExtensionContext testContext = getParentMethodExtensionContent(extensionContext);
|
||||
// Check if the test factory provided an access Id for this dynamic test.
|
||||
WithAccessId o = getMethodLevelStore(testContext).get(ACCESS_IDS_STORE_KEY, WithAccessId.class);
|
||||
if (o != null) {
|
||||
performInvocationWithAccessId(invocation, o);
|
||||
} else {
|
||||
extractAccessIdAndPerformInvocation(invocation, testContext.getRequiredTestMethod());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void interceptAfterEachMethod(
|
||||
Invocation<Void> invocation,
|
||||
ReflectiveInvocationContext<Method> invocationContext,
|
||||
ExtensionContext extensionContext) {
|
||||
extractAccessIdAndPerformInvocation(invocation, invocationContext.getExecutable());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void interceptAfterAllMethod(
|
||||
Invocation<Void> invocation,
|
||||
ReflectiveInvocationContext<Method> invocationContext,
|
||||
ExtensionContext extensionContext) {
|
||||
extractAccessIdAndPerformInvocation(invocation, invocationContext.getExecutable());
|
||||
}
|
||||
|
||||
// endregion
|
||||
|
||||
// region TestTemplateInvocationContextProvider
|
||||
|
||||
@Override
|
||||
public boolean supportsTestTemplate(ExtensionContext context) {
|
||||
return isAnnotated(context.getElement(), WithAccessIds.class)
|
||||
|| isAnnotated(context.getElement(), WithAccessId.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Stream<TestTemplateInvocationContext> provideTestTemplateInvocationContexts(
|
||||
ExtensionContext context) {
|
||||
List<WithAccessId> accessIds =
|
||||
AnnotationSupport.findRepeatableAnnotations(context.getElement(), WithAccessId.class);
|
||||
Store store = getMethodLevelStore(context);
|
||||
return accessIds.stream()
|
||||
.peek(a -> store.put(ACCESS_IDS_STORE_KEY, a))
|
||||
.map(JaasExtensionInvocationContext::new);
|
||||
}
|
||||
|
||||
// endregion
|
||||
|
||||
private static void persistDynamicContainerChildren(
|
||||
Iterable<DynamicNode> nodes, Map<String, List<DynamicNode>> childrenMap) {
|
||||
nodes.forEach(
|
||||
node -> {
|
||||
if (node instanceof DynamicContainer) {
|
||||
DynamicContainer container = (DynamicContainer) node;
|
||||
List<DynamicNode> children = container.getChildren().collect(Collectors.toList());
|
||||
childrenMap.put(container.hashCode() + container.getDisplayName(), children);
|
||||
persistDynamicContainerChildren(children, childrenMap);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static DynamicNode duplicateDynamicNode(
|
||||
DynamicNode node, Map<String, List<DynamicNode>> lookupMap) {
|
||||
if (node instanceof DynamicContainer) {
|
||||
DynamicContainer container = (DynamicContainer) node;
|
||||
Stream<DynamicNode> children =
|
||||
lookupMap.get(node.hashCode() + node.getDisplayName()).stream()
|
||||
.map(x -> duplicateDynamicNode(x, lookupMap));
|
||||
return DynamicContainer.dynamicContainer(container.getDisplayName(), children);
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
private static <T> T extractAccessIdAndPerformInvocation(
|
||||
Invocation<T> invocation, AnnotatedElement executable) {
|
||||
return performInvocationWithAccessId(invocation, executable.getAnnotation(WithAccessId.class));
|
||||
}
|
||||
|
||||
private static <T> T performInvocationWithAccessId(
|
||||
Invocation<T> invocation, WithAccessId withAccessId) {
|
||||
Subject subject = new Subject();
|
||||
subject.getPrincipals().addAll(getPrincipals(withAccessId));
|
||||
|
||||
Function<Invocation<T>, T> proceedInvocation =
|
||||
wrapExceptFor(Invocation::proceed, TestAbortedException.class);
|
||||
PrivilegedAction<T> performInvocation = () -> proceedInvocation.apply(invocation);
|
||||
return Subject.doAs(subject, performInvocation);
|
||||
}
|
||||
|
||||
private static List<Principal> getPrincipals(WithAccessId withAccessId) {
|
||||
if (withAccessId != null) {
|
||||
return Stream.concat(
|
||||
Stream.of(withAccessId.user()).map(UserPrincipal::new),
|
||||
Arrays.stream(withAccessId.groups()).map(GroupPrincipal::new))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
private ExtensionContext getParentMethodExtensionContent(ExtensionContext extensionContext) {
|
||||
Optional<ExtensionContext> parent = extensionContext.getParent();
|
||||
// the class MethodExtensionContext is part of junit-jupiter-engine and has only a
|
||||
// package-private visibility thus this workaround is needed.
|
||||
while (!parent
|
||||
.map(Object::getClass)
|
||||
.map(Class::getName)
|
||||
.filter(s -> s.endsWith("MethodExtensionContext"))
|
||||
.isPresent()) {
|
||||
parent = parent.flatMap(ExtensionContext::getParent);
|
||||
}
|
||||
return parent.orElseThrow(
|
||||
() ->
|
||||
new JUnitException(
|
||||
String.format(
|
||||
"Test '%s' does not have a parent method", extensionContext.getUniqueId())));
|
||||
}
|
||||
|
||||
private static Store getMethodLevelStore(ExtensionContext context) {
|
||||
return context.getStore(
|
||||
Namespace.create(context.getRequiredTestClass(), context.getRequiredTestMethod()));
|
||||
}
|
||||
|
||||
private static String getDisplayNameForAccessId(WithAccessId withAccessId) {
|
||||
return String.format("for user '%s'", withAccessId.user());
|
||||
}
|
||||
|
||||
private static class JaasExtensionInvocationContext implements TestTemplateInvocationContext {
|
||||
|
||||
private final WithAccessId withAccessId;
|
||||
|
||||
private JaasExtensionInvocationContext(WithAccessId withAccessId) {
|
||||
this.withAccessId = withAccessId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDisplayName(int invocationIndex) {
|
||||
return getDisplayNameForAccessId(withAccessId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Extension> getAdditionalExtensions() {
|
||||
return Collections.singletonList(new WithAccessIdParameterResolver());
|
||||
}
|
||||
|
||||
private class WithAccessIdParameterResolver implements ParameterResolver {
|
||||
|
||||
@Override
|
||||
public boolean supportsParameter(
|
||||
ParameterContext parameterContext, ExtensionContext extensionContext) {
|
||||
return parameterContext.getParameter().getType().equals(WithAccessId.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object resolveParameter(
|
||||
ParameterContext parameterContext, ExtensionContext extensionContext) {
|
||||
return withAccessId;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
package pro.taskana.testapi.security;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Repeatable;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target({ElementType.METHOD, ElementType.CONSTRUCTOR})
|
||||
@Repeatable(WithAccessId.WithAccessIds.class)
|
||||
public @interface WithAccessId {
|
||||
|
||||
String user();
|
||||
|
||||
String[] groups() default {};
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.METHOD)
|
||||
@interface WithAccessIds {
|
||||
|
||||
WithAccessId[] value();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
package pro.taskana.testapi.util;
|
||||
|
||||
import static org.junit.platform.commons.support.AnnotationSupport.isAnnotated;
|
||||
|
||||
import org.junit.jupiter.api.extension.ExtensionContext;
|
||||
import org.junit.jupiter.api.extension.ExtensionContext.Namespace;
|
||||
import org.junit.jupiter.api.extension.ExtensionContext.Store;
|
||||
|
||||
import pro.taskana.testapi.CleanTaskanaContext;
|
||||
import pro.taskana.testapi.TaskanaEngineConfigurationModifier;
|
||||
import pro.taskana.testapi.WithServiceProvider;
|
||||
|
||||
public class ExtensionCommunicator {
|
||||
|
||||
private ExtensionCommunicator() {
|
||||
throw new IllegalStateException("utility class");
|
||||
}
|
||||
|
||||
public static boolean isTopLevelClass(Class<?> testClass) {
|
||||
return testClass.getEnclosingClass() == null;
|
||||
}
|
||||
|
||||
public static Store getClassLevelStore(ExtensionContext context) {
|
||||
return getClassLevelStore(context, context.getRequiredTestClass());
|
||||
}
|
||||
|
||||
public static Store getClassLevelStore(ExtensionContext context, Class<?> testClass) {
|
||||
return context.getStore(determineNamespace(testClass));
|
||||
}
|
||||
|
||||
public static Class<?> getTopLevelClass(Class<?> testClazz) {
|
||||
Class<?> parent = testClazz;
|
||||
while (parent.getEnclosingClass() != null) {
|
||||
parent = parent.getEnclosingClass();
|
||||
}
|
||||
return parent;
|
||||
}
|
||||
|
||||
private static Namespace determineNamespace(Class<?> testClass) {
|
||||
if (isTopLevelClass(testClass)) {
|
||||
return Namespace.create(testClass);
|
||||
} else if (isAnnotated(testClass, CleanTaskanaContext.class)) {
|
||||
return Namespace.create(getTopLevelClass(testClass), testClass, CleanTaskanaContext.class);
|
||||
} else if (isAnnotated(testClass, WithServiceProvider.class)) {
|
||||
return Namespace.create(getTopLevelClass(testClass), testClass, WithServiceProvider.class);
|
||||
} else if (TaskanaEngineConfigurationModifier.class.isAssignableFrom(testClass)) {
|
||||
return Namespace.create(
|
||||
getTopLevelClass(testClass), testClass, TaskanaEngineConfigurationModifier.class);
|
||||
}
|
||||
return Namespace.create(getTopLevelClass(testClass));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,73 @@
|
|||
package pro.taskana.testapi.util;
|
||||
|
||||
import static org.junit.platform.commons.support.AnnotationSupport.findRepeatableAnnotations;
|
||||
import static pro.taskana.common.internal.util.CheckedFunction.wrap;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import org.junit.platform.commons.JUnitException;
|
||||
|
||||
import pro.taskana.spi.history.api.TaskanaHistory;
|
||||
import pro.taskana.spi.priority.api.PriorityServiceProvider;
|
||||
import pro.taskana.spi.routing.api.TaskRoutingProvider;
|
||||
import pro.taskana.spi.task.api.CreateTaskPreprocessor;
|
||||
import pro.taskana.testapi.WithServiceProvider;
|
||||
|
||||
public class ServiceProviderExtractor {
|
||||
|
||||
private static final Set<Class<?>> TASKANA_SERVICE_PROVIDER_INTERFACES =
|
||||
Set.of(
|
||||
TaskanaHistory.class,
|
||||
PriorityServiceProvider.class,
|
||||
TaskRoutingProvider.class,
|
||||
CreateTaskPreprocessor.class);
|
||||
|
||||
private ServiceProviderExtractor() {
|
||||
throw new IllegalStateException("utility class");
|
||||
}
|
||||
|
||||
public static Map<Class<?>, List<Object>> extractServiceProviders(Class<?> testClass) {
|
||||
List<WithServiceProvider> withServiceProviders =
|
||||
findRepeatableAnnotations(testClass, WithServiceProvider.class);
|
||||
|
||||
return groupServiceProvidersByServiceProviderInterface(withServiceProviders).entrySet().stream()
|
||||
.peek(entry -> validateServiceProviders(entry.getKey(), entry.getValue()))
|
||||
.collect(
|
||||
Collectors.toMap(
|
||||
Entry::getKey, entry -> instantiateServiceProviders(entry.getValue())));
|
||||
}
|
||||
|
||||
private static void validateServiceProviders(Class<?> spi, List<Class<?>> serviceProviders) {
|
||||
if (!TASKANA_SERVICE_PROVIDER_INTERFACES.contains(spi)) {
|
||||
throw new JUnitException(String.format("SPI '%s' is not a TASKANA SPI.", spi));
|
||||
}
|
||||
if (!serviceProviders.stream().allMatch(spi::isAssignableFrom)) {
|
||||
throw new JUnitException(
|
||||
String.format(
|
||||
"At least one ServiceProvider does not implement the requested SPI '%s'", spi));
|
||||
}
|
||||
}
|
||||
|
||||
private static Map<Class<?>, List<Class<?>>> groupServiceProvidersByServiceProviderInterface(
|
||||
List<WithServiceProvider> withServiceProviders) {
|
||||
return withServiceProviders.stream()
|
||||
.collect(
|
||||
Collectors.groupingBy(
|
||||
WithServiceProvider::serviceProviderInterface,
|
||||
Collectors.flatMapping(
|
||||
annotation -> Arrays.stream(annotation.serviceProviders()),
|
||||
Collectors.toList())));
|
||||
}
|
||||
|
||||
private static List<Object> instantiateServiceProviders(List<Class<?>> serviceProviders) {
|
||||
return serviceProviders.stream()
|
||||
.map(wrap(Class::getDeclaredConstructor))
|
||||
.map(wrap(Constructor::newInstance))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,184 @@
|
|||
package pro.taskana.testapi.tests;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import pro.taskana.TaskanaEngineConfiguration;
|
||||
import pro.taskana.classification.api.ClassificationService;
|
||||
import pro.taskana.classification.internal.ClassificationServiceImpl;
|
||||
import pro.taskana.common.api.ConfigurationService;
|
||||
import pro.taskana.common.api.JobService;
|
||||
import pro.taskana.common.api.TaskanaEngine;
|
||||
import pro.taskana.common.api.WorkingDaysToDaysConverter;
|
||||
import pro.taskana.common.api.security.CurrentUserContext;
|
||||
import pro.taskana.common.internal.ConfigurationMapper;
|
||||
import pro.taskana.common.internal.ConfigurationServiceImpl;
|
||||
import pro.taskana.common.internal.InternalTaskanaEngine;
|
||||
import pro.taskana.common.internal.JobServiceImpl;
|
||||
import pro.taskana.common.internal.TaskanaEngineImpl;
|
||||
import pro.taskana.common.internal.security.CurrentUserContextImpl;
|
||||
import pro.taskana.monitor.api.MonitorService;
|
||||
import pro.taskana.monitor.internal.MonitorServiceImpl;
|
||||
import pro.taskana.task.api.TaskService;
|
||||
import pro.taskana.task.internal.TaskServiceImpl;
|
||||
import pro.taskana.testapi.TaskanaInject;
|
||||
import pro.taskana.testapi.TaskanaIntegrationTest;
|
||||
import pro.taskana.workbasket.api.WorkbasketService;
|
||||
import pro.taskana.workbasket.internal.WorkbasketServiceImpl;
|
||||
|
||||
@TaskanaIntegrationTest
|
||||
class TaskanaDependencyInjectionExtensionTest {
|
||||
|
||||
TaskanaEngineConfiguration taskanaEngineConfigurationNotAnnotated;
|
||||
@TaskanaInject TaskanaEngineConfiguration taskanaEngineConfiguration;
|
||||
@TaskanaInject TaskanaEngine taskanaEngine;
|
||||
@TaskanaInject TaskanaEngine taskanaEngine2;
|
||||
@TaskanaInject TaskanaEngineImpl taskanaEngineImpl;
|
||||
@TaskanaInject InternalTaskanaEngine internalTaskanaEngine;
|
||||
@TaskanaInject ClassificationService classificationService;
|
||||
@TaskanaInject ClassificationServiceImpl classificationServiceImpl;
|
||||
@TaskanaInject WorkbasketService workbasketService;
|
||||
@TaskanaInject WorkbasketServiceImpl workbasketServiceImpl;
|
||||
@TaskanaInject TaskService taskService;
|
||||
@TaskanaInject TaskServiceImpl taskServiceImpl;
|
||||
@TaskanaInject MonitorService monitorService;
|
||||
@TaskanaInject MonitorServiceImpl monitorServiceImpl;
|
||||
@TaskanaInject JobService jobService;
|
||||
@TaskanaInject JobServiceImpl jobServiceImpl;
|
||||
@TaskanaInject ConfigurationService configurationService;
|
||||
@TaskanaInject ConfigurationServiceImpl configurationServiceImpl;
|
||||
@TaskanaInject WorkingDaysToDaysConverter workingDaysToDaysConverter;
|
||||
@TaskanaInject CurrentUserContext currentUserContext;
|
||||
@TaskanaInject CurrentUserContextImpl currentUserContextImpl;
|
||||
@TaskanaInject ConfigurationMapper configurationMapper;
|
||||
|
||||
@Test
|
||||
void should_NotInjectTaskanaEngineConfiguration_When_FieldIsNotAnnotated() {
|
||||
assertThat(taskanaEngineConfigurationNotAnnotated).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
void should_InjectMultipleTimes_When_FieldIsDeclaredMultipleTimes() {
|
||||
assertThat(taskanaEngine).isSameAs(taskanaEngine2).isNotNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
void should_InjectTaskanaEngineConfiguration_When_FieldIsAnnotatedOrDeclaredAsParameter(
|
||||
TaskanaEngineConfiguration taskanaEngineConfiguration) {
|
||||
assertThat(taskanaEngineConfiguration).isSameAs(this.taskanaEngineConfiguration).isNotNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
void should_InjectTaskanaEngine_When_FieldIsAnnotatedOrDeclaredAsParameter(
|
||||
TaskanaEngine taskanaEngine) {
|
||||
assertThat(taskanaEngine).isSameAs(this.taskanaEngine).isNotNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
void should_InjectTaskanaEngineImpl_When_FieldIsAnnotatedOrDeclaredAsParameter(
|
||||
TaskanaEngineImpl taskanaEngineImpl) {
|
||||
assertThat(taskanaEngineImpl).isSameAs(this.taskanaEngineImpl).isNotNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
void should_InjectInternalTaskanaEngine_When_FieldIsAnnotatedOrDeclaredAsParameter(
|
||||
InternalTaskanaEngine internalTaskanaEngine) {
|
||||
assertThat(internalTaskanaEngine).isSameAs(this.internalTaskanaEngine).isNotNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
void should_InjectClassificationService_When_FieldIsAnnotatedOrDeclaredAsParameter(
|
||||
ClassificationService classificationService) {
|
||||
assertThat(classificationService).isSameAs(this.classificationService).isNotNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
void should_InjectClassificationServiceImpl_When_FieldIsAnnotatedOrDeclaredAsParameter(
|
||||
ClassificationServiceImpl classificationServiceImpl) {
|
||||
assertThat(classificationServiceImpl).isSameAs(this.classificationServiceImpl).isNotNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
void should_InjectWorkbasketService_When_FieldIsAnnotatedOrDeclaredAsParameter(
|
||||
WorkbasketService workbasketService) {
|
||||
assertThat(workbasketService).isSameAs(this.workbasketService).isNotNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
void should_InjectWorkbasketServiceImpl_When_FieldIsAnnotatedOrDeclaredAsParameter(
|
||||
WorkbasketServiceImpl workbasketServiceImpl) {
|
||||
assertThat(workbasketServiceImpl).isSameAs(this.workbasketServiceImpl).isNotNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
void should_InjectTaskService_When_FieldIsAnnotatedOrDeclaredAsParameter(
|
||||
TaskService taskService) {
|
||||
assertThat(taskService).isSameAs(this.taskService).isNotNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
void should_InjectTaskServiceImpl_When_FieldIsAnnotatedOrDeclaredAsParameter(
|
||||
TaskServiceImpl taskServiceImpl) {
|
||||
assertThat(taskServiceImpl).isSameAs(this.taskServiceImpl).isNotNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
void should_InjectMonitorService_When_FieldIsAnnotatedOrDeclaredAsParameter(
|
||||
MonitorService monitorService) {
|
||||
assertThat(monitorService).isSameAs(this.monitorService).isNotNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
void should_InjectMonitorServiceImpl_When_FieldIsAnnotatedOrDeclaredAsParameter(
|
||||
MonitorServiceImpl monitorServiceImpl) {
|
||||
assertThat(monitorServiceImpl).isSameAs(this.monitorServiceImpl).isNotNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
void should_InjectJobService_When_FieldIsAnnotatedOrDeclaredAsParameter(JobService jobService) {
|
||||
assertThat(jobService).isSameAs(this.jobService).isNotNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
void should_InjectJobServiceImpl_When_FieldIsAnnotatedOrDeclaredAsParameter(
|
||||
JobServiceImpl jobServiceImpl) {
|
||||
assertThat(jobServiceImpl).isSameAs(this.jobServiceImpl).isNotNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
void should_InjectConfigurationService_When_FieldIsAnnotatedOrDeclaredAsParameter(
|
||||
ConfigurationService configurationService) {
|
||||
assertThat(configurationService).isSameAs(this.configurationService).isNotNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
void should_InjectConfigurationServiceImpl_When_FieldIsAnnotatedOrDeclaredAsParameter(
|
||||
ConfigurationServiceImpl configurationServiceImpl) {
|
||||
assertThat(configurationServiceImpl).isSameAs(this.configurationServiceImpl).isNotNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
void should_InjectWorkingDaysToDaysConverter_When_FieldIsAnnotatedOrDeclaredAsParameter(
|
||||
WorkingDaysToDaysConverter workingDaysToDaysConverter) {
|
||||
assertThat(workingDaysToDaysConverter).isSameAs(this.workingDaysToDaysConverter).isNotNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
void should_InjectCurrentUserContext_When_FieldIsAnnotatedOrDeclaredAsParameter(
|
||||
CurrentUserContext currentUserContext) {
|
||||
assertThat(currentUserContext).isSameAs(this.currentUserContext).isNotNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
void should_InjectCurrentUserContextImpl_When_FieldIsAnnotatedOrDeclaredAsParameter(
|
||||
CurrentUserContextImpl currentUserContextImpl) {
|
||||
assertThat(currentUserContextImpl).isSameAs(this.currentUserContextImpl).isNotNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
void should_InjectConfigurationMapper_When_FieldIsAnnotatedOrDeclaredAsParameter(
|
||||
ConfigurationMapper configurationMapper) {
|
||||
assertThat(configurationMapper).isSameAs(this.configurationMapper).isNotNull();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,107 @@
|
|||
package pro.taskana.testapi.tests;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
import java.util.List;
|
||||
import org.junit.jupiter.api.Nested;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.TestInstance;
|
||||
import org.junit.jupiter.api.TestInstance.Lifecycle;
|
||||
|
||||
import pro.taskana.TaskanaEngineConfiguration;
|
||||
import pro.taskana.spi.priority.api.PriorityServiceProvider;
|
||||
import pro.taskana.testapi.CleanTaskanaContext;
|
||||
import pro.taskana.testapi.TaskanaEngineConfigurationModifier;
|
||||
import pro.taskana.testapi.TaskanaInject;
|
||||
import pro.taskana.testapi.TaskanaIntegrationTest;
|
||||
import pro.taskana.testapi.WithServiceProvider;
|
||||
|
||||
@TaskanaIntegrationTest
|
||||
class TaskanaInitializationExtensionTest {
|
||||
|
||||
@TaskanaInject TaskanaEngineConfiguration taskanaEngineConfiguration;
|
||||
|
||||
@Test
|
||||
void should_UseDefaultTaskanaEngine_When_TestIsCreated() {
|
||||
assertThat(taskanaEngineConfiguration.getDomains())
|
||||
.containsExactlyInAnyOrder("DOMAIN_A", "DOMAIN_B");
|
||||
}
|
||||
|
||||
@Nested
|
||||
@TestInstance(Lifecycle.PER_CLASS)
|
||||
class ReuseTaskana {
|
||||
|
||||
@TaskanaInject TaskanaEngineConfiguration taskanaEngineConfiguration;
|
||||
|
||||
@Test
|
||||
void should_useTopLevelTaskanaInstance_For_NestedTestClasses() {
|
||||
assertThat(taskanaEngineConfiguration)
|
||||
.isSameAs(TaskanaInitializationExtensionTest.this.taskanaEngineConfiguration);
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
@TestInstance(Lifecycle.PER_CLASS)
|
||||
class ModifiedTaskanaEngineConfig implements TaskanaEngineConfigurationModifier {
|
||||
|
||||
@TaskanaInject TaskanaEngineConfiguration taskanaEngineConfiguration;
|
||||
|
||||
@Override
|
||||
public void modify(TaskanaEngineConfiguration taskanaEngineConfiguration) {
|
||||
taskanaEngineConfiguration.setDomains(List.of("A", "B"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void should_OverrideConfiguration_When_ClassImplementsTaskanaEngineConfigurationModifier() {
|
||||
assertThat(taskanaEngineConfiguration.getDomains()).containsExactlyInAnyOrder("A", "B");
|
||||
}
|
||||
|
||||
@Test
|
||||
void should_createNewTaskanaInstance_For_NestedTestClassImplementingModifierInterface() {
|
||||
assertThat(taskanaEngineConfiguration)
|
||||
.isNotSameAs(TaskanaInitializationExtensionTest.this.taskanaEngineConfiguration);
|
||||
}
|
||||
}
|
||||
|
||||
@CleanTaskanaContext
|
||||
@Nested
|
||||
@TestInstance(Lifecycle.PER_CLASS)
|
||||
class NestedTestClassAnnotatedWithCleanTaskanaContext {
|
||||
|
||||
@TaskanaInject TaskanaEngineConfiguration taskanaEngineConfiguration;
|
||||
|
||||
@Test
|
||||
void should_createNewTaskanaInstance_For_NestedTestClassAnnotatedWithCleanTaskanaContext() {
|
||||
assertThat(taskanaEngineConfiguration)
|
||||
.isNotSameAs(TaskanaInitializationExtensionTest.this.taskanaEngineConfiguration);
|
||||
}
|
||||
|
||||
@Test
|
||||
void should_UseDefaultTaskanaEngine_When_NestedClassDoesNotImplementModifier() {
|
||||
assertThat(taskanaEngineConfiguration.getDomains())
|
||||
.containsExactlyInAnyOrder("DOMAIN_A", "DOMAIN_B");
|
||||
}
|
||||
}
|
||||
|
||||
@WithServiceProvider(
|
||||
serviceProviderInterface = PriorityServiceProvider.class,
|
||||
serviceProviders = TestPriorityServiceProvider.class)
|
||||
@Nested
|
||||
@TestInstance(Lifecycle.PER_CLASS)
|
||||
class NestedTestClassWithServiceProvider {
|
||||
|
||||
@TaskanaInject TaskanaEngineConfiguration taskanaEngineConfiguration;
|
||||
|
||||
@Test
|
||||
void should_createNewTaskanaInstance_For_NestedTestClassAnnotatedWithCleanTaskanaContext() {
|
||||
assertThat(taskanaEngineConfiguration)
|
||||
.isNotSameAs(TaskanaInitializationExtensionTest.this.taskanaEngineConfiguration);
|
||||
}
|
||||
|
||||
@Test
|
||||
void should_UseDefaultTaskanaEngine_When_NestedClassDoesNotImplementModifier() {
|
||||
assertThat(taskanaEngineConfiguration.getDomains())
|
||||
.containsExactlyInAnyOrder("DOMAIN_A", "DOMAIN_B");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,172 @@
|
|||
package pro.taskana.testapi.tests;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
import java.sql.Connection;
|
||||
import javax.sql.DataSource;
|
||||
import org.junit.jupiter.api.Nested;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.TestInstance;
|
||||
import org.junit.jupiter.api.TestInstance.Lifecycle;
|
||||
|
||||
import pro.taskana.TaskanaEngineConfiguration;
|
||||
import pro.taskana.spi.priority.api.PriorityServiceProvider;
|
||||
import pro.taskana.testapi.CleanTaskanaContext;
|
||||
import pro.taskana.testapi.TaskanaEngineConfigurationModifier;
|
||||
import pro.taskana.testapi.TaskanaInject;
|
||||
import pro.taskana.testapi.TaskanaIntegrationTest;
|
||||
import pro.taskana.testapi.WithServiceProvider;
|
||||
|
||||
@TaskanaIntegrationTest
|
||||
class TestContainerExtensionTest {
|
||||
|
||||
@TaskanaInject TaskanaEngineConfiguration taskanaEngineConfiguration;
|
||||
|
||||
@Test
|
||||
void should_CreateNewDataSource_For_TopLevelTestClass() {
|
||||
DataSource datasource = taskanaEngineConfiguration.getDatasource();
|
||||
|
||||
assertThat(datasource).isNotNull();
|
||||
}
|
||||
|
||||
@Nested
|
||||
@TestInstance(Lifecycle.PER_CLASS)
|
||||
class NestedTestClass {
|
||||
|
||||
@TaskanaInject TaskanaEngineConfiguration taskanaEngineConfiguration;
|
||||
|
||||
@Test
|
||||
void should_ReuseDataSource_For_NestedTestClass() {
|
||||
DataSource nestedDataSource = taskanaEngineConfiguration.getDatasource();
|
||||
DataSource topLevelDataSource =
|
||||
TestContainerExtensionTest.this.taskanaEngineConfiguration.getDatasource();
|
||||
|
||||
assertThat(nestedDataSource).isSameAs(topLevelDataSource).isNotNull();
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
@TestInstance(Lifecycle.PER_CLASS)
|
||||
class NestedTestClassWithConfigurationModifier implements TaskanaEngineConfigurationModifier {
|
||||
|
||||
@TaskanaInject TaskanaEngineConfiguration taskanaEngineConfiguration;
|
||||
|
||||
@Override
|
||||
public void modify(TaskanaEngineConfiguration taskanaEngineConfiguration) {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
@Test
|
||||
void should_ReuseDataSource_For_NestedTestClassWhichImplementsConfigurationModifier() {
|
||||
DataSource nestedDataSource = taskanaEngineConfiguration.getDatasource();
|
||||
DataSource topLevelDataSource =
|
||||
TestContainerExtensionTest.this.taskanaEngineConfiguration.getDatasource();
|
||||
|
||||
assertThat(nestedDataSource).isSameAs(topLevelDataSource).isNotNull();
|
||||
}
|
||||
}
|
||||
|
||||
@CleanTaskanaContext
|
||||
@Nested
|
||||
@TestInstance(Lifecycle.PER_CLASS)
|
||||
class NestedTestClassAnnotatedWithCleanTaskanaContext {
|
||||
|
||||
@TaskanaInject TaskanaEngineConfiguration taskanaEngineConfiguration;
|
||||
|
||||
@Test
|
||||
void should_CreateNewDataSource_For_NestedTestAnnotatedWithCleanTaskanaContext()
|
||||
throws Exception {
|
||||
DataSource nestedDataSource = taskanaEngineConfiguration.getDatasource();
|
||||
DataSource topLevelDataSource =
|
||||
TestContainerExtensionTest.this.taskanaEngineConfiguration.getDatasource();
|
||||
String nestedDataSourceUrl;
|
||||
String topLevelDataSourceUrl;
|
||||
try (Connection connection = nestedDataSource.getConnection()) {
|
||||
nestedDataSourceUrl = connection.getMetaData().getURL();
|
||||
}
|
||||
try (Connection connection = topLevelDataSource.getConnection()) {
|
||||
topLevelDataSourceUrl = connection.getMetaData().getURL();
|
||||
}
|
||||
|
||||
assertThat(nestedDataSourceUrl).isNotEqualTo(topLevelDataSourceUrl).isNotNull();
|
||||
}
|
||||
|
||||
@CleanTaskanaContext
|
||||
@Nested
|
||||
@TestInstance(Lifecycle.PER_CLASS)
|
||||
class NestedNestedTestClassAnnotatedWithCleanTaskanaContext {
|
||||
|
||||
@TaskanaInject TaskanaEngineConfiguration taskanaEngineConfiguration;
|
||||
|
||||
@Test
|
||||
void should_CreateNewDataSource_For_NestedTestAnnotatedWithCleanTaskanaContext()
|
||||
throws Exception {
|
||||
DataSource nestedNestedDataSource = taskanaEngineConfiguration.getDatasource();
|
||||
DataSource nestedDataSource =
|
||||
NestedTestClassAnnotatedWithCleanTaskanaContext.this.taskanaEngineConfiguration
|
||||
.getDatasource();
|
||||
DataSource topLevelDataSource =
|
||||
TestContainerExtensionTest.this.taskanaEngineConfiguration.getDatasource();
|
||||
String nestedNestedDataSourceUrl;
|
||||
String nestedDataSourceUrl;
|
||||
String topLevelDataSourceUrl;
|
||||
try (Connection connection = nestedNestedDataSource.getConnection()) {
|
||||
nestedNestedDataSourceUrl = connection.getMetaData().getURL();
|
||||
}
|
||||
try (Connection connection = nestedDataSource.getConnection()) {
|
||||
nestedDataSourceUrl = connection.getMetaData().getURL();
|
||||
}
|
||||
try (Connection connection = topLevelDataSource.getConnection()) {
|
||||
topLevelDataSourceUrl = connection.getMetaData().getURL();
|
||||
}
|
||||
|
||||
assertThat(nestedNestedDataSourceUrl)
|
||||
.isNotEqualTo(nestedDataSourceUrl)
|
||||
.isNotEqualTo(topLevelDataSourceUrl)
|
||||
.isNotNull();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@CleanTaskanaContext
|
||||
@Nested
|
||||
@TestInstance(Lifecycle.PER_CLASS)
|
||||
class NestedTestClassAnnotatedWithCleanTaskanaContextAndConfigModifier
|
||||
implements TaskanaEngineConfigurationModifier {
|
||||
|
||||
@TaskanaInject TaskanaEngineConfiguration taskanaEngineConfiguration;
|
||||
|
||||
@Override
|
||||
public void modify(TaskanaEngineConfiguration taskanaEngineConfiguration) {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
@Test
|
||||
void should_CreateNewDataSource_For_NestedTestAnnotatedWithCleanTaskanaContext() {
|
||||
DataSource nestedDataSource = taskanaEngineConfiguration.getDatasource();
|
||||
DataSource topLevelDataSource =
|
||||
TestContainerExtensionTest.this.taskanaEngineConfiguration.getDatasource();
|
||||
|
||||
assertThat(nestedDataSource).isNotSameAs(topLevelDataSource).isNotNull();
|
||||
}
|
||||
}
|
||||
|
||||
@WithServiceProvider(
|
||||
serviceProviderInterface = PriorityServiceProvider.class,
|
||||
serviceProviders = TestPriorityServiceProvider.class)
|
||||
@Nested
|
||||
@TestInstance(Lifecycle.PER_CLASS)
|
||||
class NestedTestClassWithServiceProvider {
|
||||
|
||||
@TaskanaInject TaskanaEngineConfiguration taskanaEngineConfiguration;
|
||||
|
||||
@Test
|
||||
void should_ReuseDataSource_For_NestedTestClassWithServiceProvider() {
|
||||
DataSource nestedDataSource = taskanaEngineConfiguration.getDatasource();
|
||||
DataSource topLevelDataSource =
|
||||
TestContainerExtensionTest.this.taskanaEngineConfiguration.getDatasource();
|
||||
|
||||
assertThat(nestedDataSource).isSameAs(topLevelDataSource).isNotNull();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
package pro.taskana.testapi.tests;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
import java.util.OptionalInt;
|
||||
|
||||
import pro.taskana.common.api.WorkingDaysToDaysConverter;
|
||||
import pro.taskana.common.api.WorkingTimeCalculator;
|
||||
import pro.taskana.spi.priority.api.PriorityServiceProvider;
|
||||
import pro.taskana.task.api.TaskCustomField;
|
||||
import pro.taskana.task.api.models.TaskSummary;
|
||||
|
||||
public class TestPriorityServiceProvider implements PriorityServiceProvider {
|
||||
|
||||
private static final int MULTIPLIER = 10;
|
||||
|
||||
private final WorkingDaysToDaysConverter converter = new WorkingDaysToDaysConverter(true, true);
|
||||
private final WorkingTimeCalculator calculator = new WorkingTimeCalculator(converter);
|
||||
|
||||
@Override
|
||||
public OptionalInt calculatePriority(TaskSummary taskSummary) {
|
||||
|
||||
long priority;
|
||||
try {
|
||||
priority =
|
||||
calculator
|
||||
.workingTimeBetweenTwoTimestamps(taskSummary.getCreated(), Instant.now())
|
||||
.toMinutes()
|
||||
+ 1;
|
||||
} catch (Exception e) {
|
||||
priority = Duration.between(taskSummary.getCreated(), Instant.now()).toMinutes();
|
||||
}
|
||||
|
||||
if (Boolean.parseBoolean(taskSummary.getCustomField(TaskCustomField.CUSTOM_6))) {
|
||||
priority *= MULTIPLIER;
|
||||
}
|
||||
|
||||
return OptionalInt.of(Math.toIntExact(priority));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,738 @@
|
|||
package pro.taskana.testapi.tests.security;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.junit.jupiter.api.DynamicContainer.dynamicContainer;
|
||||
import static org.junit.jupiter.api.DynamicTest.dynamicTest;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
import org.junit.jupiter.api.AfterAll;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.DynamicContainer;
|
||||
import org.junit.jupiter.api.DynamicTest;
|
||||
import org.junit.jupiter.api.Nested;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.TestFactory;
|
||||
import org.junit.jupiter.api.TestInstance;
|
||||
import org.junit.jupiter.api.TestInstance.Lifecycle;
|
||||
import org.junit.jupiter.api.TestTemplate;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
|
||||
import pro.taskana.common.api.security.CurrentUserContext;
|
||||
import pro.taskana.common.internal.security.CurrentUserContextImpl;
|
||||
import pro.taskana.testapi.security.JaasExtension;
|
||||
import pro.taskana.testapi.security.WithAccessId;
|
||||
import pro.taskana.testapi.tests.security.JaasExtensionTestExtensions.ShouldThrowJunitException;
|
||||
import pro.taskana.testapi.tests.security.JaasExtensionTestExtensions.ShouldThrowParameterResolutionException;
|
||||
|
||||
@ExtendWith(JaasExtension.class)
|
||||
class JaasExtensionTest {
|
||||
|
||||
private static final String INSIDE_DYNAMIC_TEST_USER = "inside_dynamic_test";
|
||||
private static final CurrentUserContext CURRENT_USER_CONTEXT = new CurrentUserContextImpl(true);
|
||||
private static final DynamicTest NOT_NULL_DYNAMIC_TEST =
|
||||
dynamicTest("dynamic test", () -> assertThat(CURRENT_USER_CONTEXT.getUserid()).isNotNull());
|
||||
private static final DynamicTest NULL_DYNAMIC_TEST =
|
||||
dynamicTest("dynamic test", () -> assertThat(CURRENT_USER_CONTEXT.getUserid()).isNull());
|
||||
private static final DynamicTest DYNAMIC_TEST_USER_DYNAMIC_TEST =
|
||||
dynamicTest(
|
||||
"dynamic test",
|
||||
() -> assertThat(CURRENT_USER_CONTEXT.getUserid()).isEqualTo(INSIDE_DYNAMIC_TEST_USER));
|
||||
|
||||
// region JaasExtension#interceptBeforeAllMethod
|
||||
|
||||
@BeforeAll
|
||||
static void should_NotSetJaasSubject_When_AnnotationIsMissing_On_BeforeAll() {
|
||||
assertThat(CURRENT_USER_CONTEXT.getUserid()).isNull();
|
||||
}
|
||||
|
||||
@WithAccessId(user = "beforeall")
|
||||
@BeforeAll
|
||||
static void should_SetJaasSubject_When_AnnotationExists_On_BeforeAll() {
|
||||
assertThat(CURRENT_USER_CONTEXT.getUserid()).isEqualTo("beforeall");
|
||||
}
|
||||
|
||||
@WithAccessId(user = "beforeall")
|
||||
@WithAccessId(user = "beforeall2")
|
||||
@BeforeAll
|
||||
static void should_NotSetJaasSubject_When_MultipleAnnotationsExist_On_BeforeAll() {
|
||||
assertThat(CURRENT_USER_CONTEXT.getUserid()).isNull();
|
||||
}
|
||||
|
||||
// endregion
|
||||
|
||||
// region JaasExtension#interceptBeforeEachMethod
|
||||
|
||||
@BeforeEach
|
||||
void should_NotSetJaasSubject_When_AnnotationIsMissing_On_BeforeEach() {
|
||||
assertThat(CURRENT_USER_CONTEXT.getUserid()).isNull();
|
||||
}
|
||||
|
||||
@WithAccessId(user = "beforeeach")
|
||||
@BeforeEach
|
||||
void should_SetJaasSubject_When_AnnotationExists_On_BeforeEach() {
|
||||
assertThat(CURRENT_USER_CONTEXT.getUserid()).isEqualTo("beforeeach");
|
||||
}
|
||||
|
||||
@WithAccessId(user = "beforeeach")
|
||||
@WithAccessId(user = "beforeeach2")
|
||||
@BeforeEach
|
||||
void should_NotSetJaasSubject_When_MultipleAnnotationsExist_On_BeforeEach() {
|
||||
assertThat(CURRENT_USER_CONTEXT.getUserid()).isNull();
|
||||
}
|
||||
|
||||
// endregion
|
||||
|
||||
// region JaasExtension#interceptAfterEachMethod
|
||||
|
||||
@AfterEach
|
||||
void should_NotSetJaasSubject_When_AnnotationIsMissing_On_AfterEach() {
|
||||
assertThat(CURRENT_USER_CONTEXT.getUserid()).isNull();
|
||||
}
|
||||
|
||||
@WithAccessId(user = "aftereach")
|
||||
@AfterEach
|
||||
void should_SetJaasSubject_When_AnnotationExists_On_AfterEach() {
|
||||
assertThat(CURRENT_USER_CONTEXT.getUserid()).isEqualTo("aftereach");
|
||||
}
|
||||
|
||||
@WithAccessId(user = "aftereach")
|
||||
@WithAccessId(user = "afterach2")
|
||||
@AfterEach
|
||||
void should_NotSetJaasSubject_When_MultipleAnnotationsExist_On_AfterEach() {
|
||||
assertThat(CURRENT_USER_CONTEXT.getUserid()).isNull();
|
||||
}
|
||||
|
||||
// endregion
|
||||
|
||||
// region JaasExtension#interceptAfterAllMethod
|
||||
|
||||
@AfterAll
|
||||
static void should_NotSetJaasSubject_When_AnnotationIsMissing_On_AfterAll() {
|
||||
assertThat(CURRENT_USER_CONTEXT.getUserid()).isNull();
|
||||
}
|
||||
|
||||
@WithAccessId(user = "afterall")
|
||||
@AfterAll
|
||||
static void should_SetJaasSubject_When_AnnotationExists_On_AfterAll() {
|
||||
assertThat(CURRENT_USER_CONTEXT.getUserid()).isEqualTo("afterall");
|
||||
}
|
||||
|
||||
@WithAccessId(user = "afterall")
|
||||
@WithAccessId(user = "afterall2")
|
||||
@AfterAll
|
||||
static void should_NotSetJaasSubject_When_MultipleAnnotationsExist_On_AfterAll() {
|
||||
assertThat(CURRENT_USER_CONTEXT.getUserid()).isNull();
|
||||
}
|
||||
|
||||
// endregion
|
||||
|
||||
// region JaasExtension#interceptTestMethod
|
||||
|
||||
@Test
|
||||
void should_NotSetJaasSubject_When_AnnotationIsMissing_On_Test() {
|
||||
assertThat(CURRENT_USER_CONTEXT.getUserid()).isNull();
|
||||
}
|
||||
|
||||
@WithAccessId(user = "user")
|
||||
@Test
|
||||
void should_SetJaasSubject_When_AnnotationExists_On_Test() {
|
||||
assertThat(CURRENT_USER_CONTEXT.getUserid()).isEqualTo("user");
|
||||
assertThat(CURRENT_USER_CONTEXT.getGroupIds()).isEmpty();
|
||||
}
|
||||
|
||||
@WithAccessId(
|
||||
user = "user",
|
||||
groups = {"group1", "group2"})
|
||||
@Test
|
||||
void should_SetJaasSubjectWithGroups_When_AnnotationExistsWithGroups_On_Test() {
|
||||
assertThat(CURRENT_USER_CONTEXT.getUserid()).isEqualTo("user");
|
||||
assertThat(CURRENT_USER_CONTEXT.getGroupIds()).containsExactlyInAnyOrder("group1", "group2");
|
||||
}
|
||||
|
||||
@WithAccessId(user = "user")
|
||||
@Test
|
||||
@ExtendWith(ShouldThrowParameterResolutionException.class)
|
||||
void should_NotInjectParameter_When_TestTemplateIsNotUsed(
|
||||
@SuppressWarnings("unused") WithAccessId accessId) {
|
||||
// THIS IS NOT RELEVANT
|
||||
assertThat(true).isTrue();
|
||||
}
|
||||
|
||||
@WithAccessId(user = "user")
|
||||
@WithAccessId(user = "user2")
|
||||
@Test
|
||||
@ExtendWith(ShouldThrowJunitException.class)
|
||||
void should_ThrowJunitException_When_MultipleAnnotationsExist_On_Test() {
|
||||
// THIS IS NOT RELEVANT
|
||||
assertThat(true).isTrue();
|
||||
}
|
||||
|
||||
// endregion
|
||||
|
||||
// region JaasExtension#interceptTestFactory
|
||||
|
||||
@TestFactory
|
||||
List<DynamicTest> should_NotSetJaasSubject_When_AnnotationIsMissing_On_TestFactory() {
|
||||
assertThat(CURRENT_USER_CONTEXT.getUserid()).isNull();
|
||||
return List.of();
|
||||
}
|
||||
|
||||
@WithAccessId(user = "testfactory")
|
||||
@TestFactory
|
||||
List<DynamicTest> should_SetJaasSubject_When_AnnotationExists_On_TestFactory() {
|
||||
assertThat(CURRENT_USER_CONTEXT.getUserid()).isEqualTo("testfactory");
|
||||
return List.of();
|
||||
}
|
||||
|
||||
@WithAccessId(user = "testfactory1")
|
||||
@WithAccessId(user = "testfactory2")
|
||||
@TestFactory
|
||||
List<DynamicTest>
|
||||
should_SetJaasSubjectFromFirstAnnotation_When_MultipleAnnotationsExists_On_TestFactory() {
|
||||
assertThat(CURRENT_USER_CONTEXT.getUserid()).isEqualTo("testfactory1");
|
||||
return List.of();
|
||||
}
|
||||
|
||||
// endregion
|
||||
|
||||
// region JaasExtension#interceptTestTemplateMethod
|
||||
|
||||
@WithAccessId(user = "testtemplate")
|
||||
@TestTemplate
|
||||
void should_SetJaasSubject_When_AnnotationExists_On_TestTemplate() {
|
||||
assertThat(CURRENT_USER_CONTEXT.getUserid()).isEqualTo("testtemplate");
|
||||
}
|
||||
|
||||
@WithAccessId(user = "testtemplate1")
|
||||
@WithAccessId(user = "testtemplate2")
|
||||
@WithAccessId(user = "testtemplate3")
|
||||
@TestTemplate
|
||||
void should_SetMultipleJaasSubjects_When_MultipleAnnotationsExist_On_TestTemplate(
|
||||
WithAccessId accessId) {
|
||||
assertThat(CURRENT_USER_CONTEXT.getUserid()).isEqualTo(accessId.user());
|
||||
}
|
||||
|
||||
@WithAccessId(user = "testtemplate1", groups = "abc")
|
||||
@TestTemplate
|
||||
void should_InjectCorrectAccessId_When_AnnotationExists_On_TestTemplate(WithAccessId accessId) {
|
||||
assertThat(accessId.user()).isEqualTo("testtemplate1");
|
||||
assertThat(accessId.groups()).containsExactly("abc");
|
||||
}
|
||||
|
||||
// endregion
|
||||
|
||||
// region JaasExtension#interceptDynamicTest
|
||||
|
||||
// region RETURNING DynamicNode
|
||||
|
||||
// WITH DynamicTest
|
||||
|
||||
@TestFactory
|
||||
DynamicTest should_NotSetAccessIdForDynamicTest_When_AnnotationIsMissing() {
|
||||
return NULL_DYNAMIC_TEST;
|
||||
}
|
||||
|
||||
@WithAccessId(user = INSIDE_DYNAMIC_TEST_USER)
|
||||
@TestFactory
|
||||
DynamicTest should_SetAccessIdForDynamicTest_When_AnnotationExists() {
|
||||
return DYNAMIC_TEST_USER_DYNAMIC_TEST;
|
||||
}
|
||||
|
||||
@WithAccessId(user = INSIDE_DYNAMIC_TEST_USER)
|
||||
@WithAccessId(user = INSIDE_DYNAMIC_TEST_USER)
|
||||
@TestFactory
|
||||
DynamicTest should_SetMultipleAccessIdForDynamicTest_When_AnnotationsExist() {
|
||||
return NOT_NULL_DYNAMIC_TEST;
|
||||
}
|
||||
|
||||
// WITH DynamicContainer
|
||||
|
||||
@TestFactory
|
||||
DynamicContainer should_NotSetAccessIdForDynamicContainer_When_AnnotationIsMissing() {
|
||||
return dynamicContainer("dynamic container", Stream.of(NULL_DYNAMIC_TEST, NULL_DYNAMIC_TEST));
|
||||
}
|
||||
|
||||
@WithAccessId(user = INSIDE_DYNAMIC_TEST_USER)
|
||||
@TestFactory
|
||||
DynamicContainer should_SetAccessIdForDynamicContainer_When_AnnotationExists() {
|
||||
return dynamicContainer(
|
||||
"dynamic container",
|
||||
Stream.of(DYNAMIC_TEST_USER_DYNAMIC_TEST, DYNAMIC_TEST_USER_DYNAMIC_TEST));
|
||||
}
|
||||
|
||||
@WithAccessId(user = INSIDE_DYNAMIC_TEST_USER)
|
||||
@WithAccessId(user = INSIDE_DYNAMIC_TEST_USER)
|
||||
@TestFactory
|
||||
DynamicContainer should_SetMultipleAccessIdForDynamicContainer_When_AnnotationsExist() {
|
||||
return dynamicContainer(
|
||||
"dynamic container", Stream.of(NOT_NULL_DYNAMIC_TEST, NOT_NULL_DYNAMIC_TEST));
|
||||
}
|
||||
|
||||
// WITH nested DynamicContainer
|
||||
|
||||
@TestFactory
|
||||
DynamicContainer should_NotSetAccessIdForNestedDynamicContainer_When_AnnotationIsMissing() {
|
||||
DynamicContainer container =
|
||||
dynamicContainer("inside container", Stream.of(NULL_DYNAMIC_TEST, NULL_DYNAMIC_TEST));
|
||||
return dynamicContainer("outside container", Stream.of(container, NULL_DYNAMIC_TEST));
|
||||
}
|
||||
|
||||
@WithAccessId(user = INSIDE_DYNAMIC_TEST_USER)
|
||||
@TestFactory
|
||||
DynamicContainer should_SetAccessIdForNestedDynamicContainer_When_AnnotationExists() {
|
||||
DynamicContainer container =
|
||||
dynamicContainer(
|
||||
"nested container",
|
||||
Stream.of(DYNAMIC_TEST_USER_DYNAMIC_TEST, DYNAMIC_TEST_USER_DYNAMIC_TEST));
|
||||
return dynamicContainer(
|
||||
"outside container", Stream.of(container, DYNAMIC_TEST_USER_DYNAMIC_TEST));
|
||||
}
|
||||
|
||||
@WithAccessId(user = INSIDE_DYNAMIC_TEST_USER)
|
||||
@WithAccessId(user = INSIDE_DYNAMIC_TEST_USER)
|
||||
@TestFactory
|
||||
DynamicContainer should_SetMultipleAccessIdForNestedDynamicContainer_When_AnnotationsExist() {
|
||||
DynamicContainer container =
|
||||
dynamicContainer(
|
||||
"inside container", Stream.of(NOT_NULL_DYNAMIC_TEST, NOT_NULL_DYNAMIC_TEST));
|
||||
return dynamicContainer("outside container", Stream.of(container, NOT_NULL_DYNAMIC_TEST));
|
||||
}
|
||||
|
||||
// endregion
|
||||
|
||||
// region RETURNING Stream<DynamicNode>
|
||||
|
||||
@TestFactory
|
||||
Stream<DynamicTest> should_NotSetAccessIdForDynamicTestInStream_When_AnnotationIsMissing() {
|
||||
return Stream.of(NULL_DYNAMIC_TEST, NULL_DYNAMIC_TEST);
|
||||
}
|
||||
|
||||
@WithAccessId(user = INSIDE_DYNAMIC_TEST_USER)
|
||||
@TestFactory
|
||||
Stream<DynamicTest> should_SetAccessIdForDynamicTestInStream_When_AnnotationExists() {
|
||||
return Stream.of(DYNAMIC_TEST_USER_DYNAMIC_TEST, DYNAMIC_TEST_USER_DYNAMIC_TEST);
|
||||
}
|
||||
|
||||
@WithAccessId(user = INSIDE_DYNAMIC_TEST_USER)
|
||||
@WithAccessId(user = INSIDE_DYNAMIC_TEST_USER)
|
||||
@TestFactory
|
||||
Stream<DynamicTest> should_SetMultipleAccessIdForDynamicTestInStream_When_AnnotationsExist() {
|
||||
return Stream.of(NOT_NULL_DYNAMIC_TEST, NOT_NULL_DYNAMIC_TEST);
|
||||
}
|
||||
|
||||
// WITH DynamicContainer
|
||||
|
||||
@TestFactory
|
||||
Stream<DynamicContainer>
|
||||
should_NotSetAccessIdForDynamicContainerInStream_When_AnnotationIsMissing() {
|
||||
Supplier<DynamicContainer> supplier =
|
||||
() ->
|
||||
dynamicContainer("dynamic container", Stream.of(NULL_DYNAMIC_TEST, NULL_DYNAMIC_TEST));
|
||||
return Stream.generate(supplier).limit(2);
|
||||
}
|
||||
|
||||
@WithAccessId(user = INSIDE_DYNAMIC_TEST_USER)
|
||||
@TestFactory
|
||||
Stream<DynamicContainer> should_SetAccessIdForDynamicContainerInStream_When_AnnotationExists() {
|
||||
Supplier<DynamicContainer> supplier =
|
||||
() ->
|
||||
dynamicContainer(
|
||||
"dynamic container",
|
||||
Stream.of(DYNAMIC_TEST_USER_DYNAMIC_TEST, DYNAMIC_TEST_USER_DYNAMIC_TEST));
|
||||
return Stream.generate(supplier).limit(2);
|
||||
}
|
||||
|
||||
@WithAccessId(user = INSIDE_DYNAMIC_TEST_USER)
|
||||
@WithAccessId(user = INSIDE_DYNAMIC_TEST_USER)
|
||||
@TestFactory
|
||||
Stream<DynamicContainer>
|
||||
should_SetMultipleAccessIdForDynamicContainerInStream_When_AnnotationsExist() {
|
||||
Supplier<DynamicContainer> supplier =
|
||||
() ->
|
||||
dynamicContainer(
|
||||
"dynamic container", Stream.of(NOT_NULL_DYNAMIC_TEST, NOT_NULL_DYNAMIC_TEST));
|
||||
return Stream.generate(supplier).limit(2);
|
||||
}
|
||||
|
||||
// WITH nested DynamicContainer
|
||||
|
||||
@TestFactory
|
||||
Stream<DynamicContainer>
|
||||
should_NotSetAccessIdForNestedDynamicContainerInStream_When_AnnotationIsMissing() {
|
||||
Supplier<DynamicContainer> supplier =
|
||||
() -> dynamicContainer("inside container", Stream.of(NULL_DYNAMIC_TEST, NULL_DYNAMIC_TEST));
|
||||
Supplier<DynamicContainer> outsideSupplier =
|
||||
() -> dynamicContainer("outside container", Stream.of(supplier.get(), NULL_DYNAMIC_TEST));
|
||||
return Stream.generate(outsideSupplier).limit(2);
|
||||
}
|
||||
|
||||
@WithAccessId(user = INSIDE_DYNAMIC_TEST_USER)
|
||||
@TestFactory
|
||||
Stream<DynamicContainer>
|
||||
should_SetAccessIdForNestedDynamicContainerInStream_When_AnnotationExists() {
|
||||
Supplier<DynamicContainer> supplier =
|
||||
() ->
|
||||
dynamicContainer(
|
||||
"inside container",
|
||||
Stream.of(DYNAMIC_TEST_USER_DYNAMIC_TEST, DYNAMIC_TEST_USER_DYNAMIC_TEST));
|
||||
Supplier<DynamicContainer> outsideSupplier =
|
||||
() ->
|
||||
dynamicContainer(
|
||||
"outside container", Stream.of(supplier.get(), DYNAMIC_TEST_USER_DYNAMIC_TEST));
|
||||
return Stream.generate(outsideSupplier).limit(2);
|
||||
}
|
||||
|
||||
@WithAccessId(user = INSIDE_DYNAMIC_TEST_USER)
|
||||
@WithAccessId(user = INSIDE_DYNAMIC_TEST_USER)
|
||||
@TestFactory
|
||||
Stream<DynamicContainer>
|
||||
should_SetMultipleAccessIdForNestedDynamicContainerInStream_When_AnnotationsExist() {
|
||||
Supplier<DynamicContainer> supplier =
|
||||
() ->
|
||||
dynamicContainer(
|
||||
"inside container", Stream.of(NOT_NULL_DYNAMIC_TEST, NOT_NULL_DYNAMIC_TEST));
|
||||
Supplier<DynamicContainer> outsideSupplier =
|
||||
() ->
|
||||
dynamicContainer("outside container", Stream.of(supplier.get(), NOT_NULL_DYNAMIC_TEST));
|
||||
return Stream.generate(outsideSupplier).limit(2);
|
||||
}
|
||||
|
||||
// endregion
|
||||
|
||||
// region RETURNING Iterable<DynamicNode>
|
||||
|
||||
@TestFactory
|
||||
Iterable<DynamicTest> should_NotSetAccessIdForDynamicTestInIterable_When_AnnotationIsMissing() {
|
||||
return Stream.of(NULL_DYNAMIC_TEST, NULL_DYNAMIC_TEST).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@WithAccessId(user = INSIDE_DYNAMIC_TEST_USER)
|
||||
@TestFactory
|
||||
Iterable<DynamicTest> should_SetAccessIdForDynamicTestInIterable_When_AnnotationExists() {
|
||||
return Stream.of(DYNAMIC_TEST_USER_DYNAMIC_TEST, DYNAMIC_TEST_USER_DYNAMIC_TEST)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@WithAccessId(user = INSIDE_DYNAMIC_TEST_USER)
|
||||
@WithAccessId(user = INSIDE_DYNAMIC_TEST_USER)
|
||||
@TestFactory
|
||||
Iterable<DynamicTest> should_SetMultipleAccessIdForDynamicTestInIterable_When_AnnotationsExist() {
|
||||
return Stream.of(NOT_NULL_DYNAMIC_TEST, NOT_NULL_DYNAMIC_TEST).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
// WITH DynamicContainer
|
||||
|
||||
@TestFactory
|
||||
Iterable<DynamicContainer>
|
||||
should_NotSetAccessIdForDynamicContainerInIterable_When_AnnotationIsMissing() {
|
||||
Supplier<DynamicContainer> supplier =
|
||||
() ->
|
||||
dynamicContainer("dynamic container", Stream.of(NULL_DYNAMIC_TEST, NULL_DYNAMIC_TEST));
|
||||
return Stream.generate(supplier).limit(2).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@WithAccessId(user = INSIDE_DYNAMIC_TEST_USER)
|
||||
@TestFactory
|
||||
Iterable<DynamicContainer>
|
||||
should_SetAccessIdForDynamicContainerInIterable_When_AnnotationExists() {
|
||||
Supplier<DynamicContainer> supplier =
|
||||
() ->
|
||||
dynamicContainer(
|
||||
"dynamic container",
|
||||
Stream.of(DYNAMIC_TEST_USER_DYNAMIC_TEST, DYNAMIC_TEST_USER_DYNAMIC_TEST));
|
||||
return Stream.generate(supplier).limit(2).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@WithAccessId(user = INSIDE_DYNAMIC_TEST_USER)
|
||||
@WithAccessId(user = INSIDE_DYNAMIC_TEST_USER)
|
||||
@TestFactory
|
||||
Iterable<DynamicContainer>
|
||||
should_SetMultipleAccessIdForDynamicContainerInIterable_When_AnnotationsExist() {
|
||||
Supplier<DynamicContainer> supplier =
|
||||
() ->
|
||||
dynamicContainer(
|
||||
"dynamic container", Stream.of(NOT_NULL_DYNAMIC_TEST, NOT_NULL_DYNAMIC_TEST));
|
||||
return Stream.generate(supplier).limit(2).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
// WITH nested DynamicContainer
|
||||
|
||||
@TestFactory
|
||||
Iterable<DynamicContainer>
|
||||
should_NotSetAccessIdForNestedDynamicContainerInIterable_When_AnnotationIsMissing() {
|
||||
Supplier<DynamicContainer> supplier =
|
||||
() -> dynamicContainer("inside container", Stream.of(NULL_DYNAMIC_TEST, NULL_DYNAMIC_TEST));
|
||||
Supplier<DynamicContainer> outsideSupplier =
|
||||
() -> dynamicContainer("outside container", Stream.of(supplier.get(), NULL_DYNAMIC_TEST));
|
||||
return Stream.generate(outsideSupplier).limit(2).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@WithAccessId(user = INSIDE_DYNAMIC_TEST_USER)
|
||||
@TestFactory
|
||||
Iterable<DynamicContainer>
|
||||
should_SetAccessIdForNestedDynamicContainerInIterable_When_AnnotationExists() {
|
||||
Supplier<DynamicContainer> supplier =
|
||||
() ->
|
||||
dynamicContainer(
|
||||
"inside container",
|
||||
Stream.of(DYNAMIC_TEST_USER_DYNAMIC_TEST, DYNAMIC_TEST_USER_DYNAMIC_TEST));
|
||||
Supplier<DynamicContainer> outsideSupplier =
|
||||
() ->
|
||||
dynamicContainer(
|
||||
"outside container", Stream.of(supplier.get(), DYNAMIC_TEST_USER_DYNAMIC_TEST));
|
||||
return Stream.generate(outsideSupplier).limit(2).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@WithAccessId(user = INSIDE_DYNAMIC_TEST_USER)
|
||||
@WithAccessId(user = INSIDE_DYNAMIC_TEST_USER)
|
||||
@TestFactory
|
||||
Iterable<DynamicContainer>
|
||||
should_SetMultipleAccessIdForNestedDynamicContainerInIterable_When_AnnotationsExist() {
|
||||
Supplier<DynamicContainer> supplier =
|
||||
() ->
|
||||
dynamicContainer(
|
||||
"inside container", Stream.of(NOT_NULL_DYNAMIC_TEST, NOT_NULL_DYNAMIC_TEST));
|
||||
Supplier<DynamicContainer> outsideSupplier =
|
||||
() ->
|
||||
dynamicContainer("outside container", Stream.of(supplier.get(), NOT_NULL_DYNAMIC_TEST));
|
||||
return Stream.generate(outsideSupplier).limit(2).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
// endregion
|
||||
|
||||
// region RETURNING Iterator<DynamicNode>
|
||||
|
||||
@TestFactory
|
||||
Iterator<DynamicTest> should_NotSetAccessIdForDynamicTestInIterator_When_AnnotationIsMissing() {
|
||||
return Stream.of(NULL_DYNAMIC_TEST, NULL_DYNAMIC_TEST).iterator();
|
||||
}
|
||||
|
||||
@WithAccessId(user = INSIDE_DYNAMIC_TEST_USER)
|
||||
@TestFactory
|
||||
Iterator<DynamicTest> should_SetAccessIdForDynamicTestInIterator_When_AnnotationExists() {
|
||||
return Stream.of(DYNAMIC_TEST_USER_DYNAMIC_TEST, DYNAMIC_TEST_USER_DYNAMIC_TEST).iterator();
|
||||
}
|
||||
|
||||
@WithAccessId(user = INSIDE_DYNAMIC_TEST_USER)
|
||||
@WithAccessId(user = INSIDE_DYNAMIC_TEST_USER)
|
||||
@TestFactory
|
||||
Iterator<DynamicTest> should_SetMultipleAccessIdForDynamicTestInIterator_When_AnnotationsExist() {
|
||||
return Stream.of(NOT_NULL_DYNAMIC_TEST, NOT_NULL_DYNAMIC_TEST).iterator();
|
||||
}
|
||||
|
||||
// WITH DynamicContainer
|
||||
|
||||
@TestFactory
|
||||
Iterator<DynamicContainer>
|
||||
should_NotSetAccessIdForDynamicContainerInIterator_When_AnnotationIsMissing() {
|
||||
Supplier<DynamicContainer> supplier =
|
||||
() ->
|
||||
dynamicContainer("dynamic container", Stream.of(NULL_DYNAMIC_TEST, NULL_DYNAMIC_TEST));
|
||||
return Stream.generate(supplier).limit(2).iterator();
|
||||
}
|
||||
|
||||
@WithAccessId(user = INSIDE_DYNAMIC_TEST_USER)
|
||||
@TestFactory
|
||||
Iterator<DynamicContainer>
|
||||
should_SetAccessIdForDynamicContainerInIterator_When_AnnotationExists() {
|
||||
Supplier<DynamicContainer> supplier =
|
||||
() ->
|
||||
dynamicContainer(
|
||||
"dynamic container",
|
||||
Stream.of(DYNAMIC_TEST_USER_DYNAMIC_TEST, DYNAMIC_TEST_USER_DYNAMIC_TEST));
|
||||
return Stream.generate(supplier).limit(2).iterator();
|
||||
}
|
||||
|
||||
@WithAccessId(user = INSIDE_DYNAMIC_TEST_USER)
|
||||
@WithAccessId(user = INSIDE_DYNAMIC_TEST_USER)
|
||||
@TestFactory
|
||||
Iterator<DynamicContainer>
|
||||
should_SetMultipleAccessIdForDynamicContainerInIterator_When_AnnotationsExist() {
|
||||
Supplier<DynamicContainer> supplier =
|
||||
() ->
|
||||
dynamicContainer(
|
||||
"dynamic container", Stream.of(NOT_NULL_DYNAMIC_TEST, NOT_NULL_DYNAMIC_TEST));
|
||||
return Stream.generate(supplier).limit(2).iterator();
|
||||
}
|
||||
|
||||
// WITH nested DynamicContainer
|
||||
|
||||
@TestFactory
|
||||
Iterator<DynamicContainer>
|
||||
should_NotSetAccessIdForNestedDynamicContainerInIterator_When_AnnotationIsMissing() {
|
||||
Supplier<DynamicContainer> supplier =
|
||||
() -> dynamicContainer("inside container", Stream.of(NULL_DYNAMIC_TEST, NULL_DYNAMIC_TEST));
|
||||
Supplier<DynamicContainer> outsideSupplier =
|
||||
() -> dynamicContainer("outside container", Stream.of(supplier.get(), NULL_DYNAMIC_TEST));
|
||||
return Stream.generate(outsideSupplier).limit(2).iterator();
|
||||
}
|
||||
|
||||
@WithAccessId(user = INSIDE_DYNAMIC_TEST_USER)
|
||||
@TestFactory
|
||||
Iterator<DynamicContainer>
|
||||
should_SetAccessIdForNestedDynamicContainerInIterator_When_AnnotationExists() {
|
||||
Supplier<DynamicContainer> supplier =
|
||||
() ->
|
||||
dynamicContainer(
|
||||
"inside container",
|
||||
Stream.of(DYNAMIC_TEST_USER_DYNAMIC_TEST, DYNAMIC_TEST_USER_DYNAMIC_TEST));
|
||||
Supplier<DynamicContainer> outsideSupplier =
|
||||
() ->
|
||||
dynamicContainer(
|
||||
"outside container", Stream.of(supplier.get(), DYNAMIC_TEST_USER_DYNAMIC_TEST));
|
||||
return Stream.generate(outsideSupplier).limit(2).iterator();
|
||||
}
|
||||
|
||||
@WithAccessId(user = INSIDE_DYNAMIC_TEST_USER)
|
||||
@WithAccessId(user = INSIDE_DYNAMIC_TEST_USER)
|
||||
@TestFactory
|
||||
Iterator<DynamicContainer>
|
||||
should_SetMultipleAccessIdForNestedDynamicContainerInIterator_When_AnnotationsExist() {
|
||||
Supplier<DynamicContainer> supplier =
|
||||
() ->
|
||||
dynamicContainer(
|
||||
"inside container", Stream.of(NOT_NULL_DYNAMIC_TEST, NOT_NULL_DYNAMIC_TEST));
|
||||
Supplier<DynamicContainer> outsideSupplier =
|
||||
() ->
|
||||
dynamicContainer("outside container", Stream.of(supplier.get(), NOT_NULL_DYNAMIC_TEST));
|
||||
return Stream.generate(outsideSupplier).limit(2).iterator();
|
||||
}
|
||||
|
||||
// endregion
|
||||
|
||||
// region RETURNING DynamicNode[]
|
||||
|
||||
@TestFactory
|
||||
DynamicTest[] should_NotSetAccessIdForDynamicTestInArray_When_AnnotationIsMissing() {
|
||||
return Stream.of(NULL_DYNAMIC_TEST, NULL_DYNAMIC_TEST).toArray(DynamicTest[]::new);
|
||||
}
|
||||
|
||||
@WithAccessId(user = INSIDE_DYNAMIC_TEST_USER)
|
||||
@TestFactory
|
||||
DynamicTest[] should_SetAccessIdForDynamicTestInArray_When_AnnotationExists() {
|
||||
return Stream.of(DYNAMIC_TEST_USER_DYNAMIC_TEST, DYNAMIC_TEST_USER_DYNAMIC_TEST)
|
||||
.toArray(DynamicTest[]::new);
|
||||
}
|
||||
|
||||
@WithAccessId(user = INSIDE_DYNAMIC_TEST_USER)
|
||||
@WithAccessId(user = INSIDE_DYNAMIC_TEST_USER)
|
||||
@TestFactory
|
||||
DynamicTest[] should_SetMultipleAccessIdForDynamicTestInArray_When_AnnotationsExist() {
|
||||
return Stream.of(NOT_NULL_DYNAMIC_TEST, NOT_NULL_DYNAMIC_TEST).toArray(DynamicTest[]::new);
|
||||
}
|
||||
|
||||
// WITH DynamicContainer
|
||||
|
||||
@TestFactory
|
||||
DynamicContainer[] should_NotSetAccessIdForDynamicContainerInArray_When_AnnotationIsMissing() {
|
||||
Supplier<DynamicContainer> supplier =
|
||||
() ->
|
||||
dynamicContainer("dynamic container", Stream.of(NULL_DYNAMIC_TEST, NULL_DYNAMIC_TEST));
|
||||
return Stream.generate(supplier).limit(2).toArray(DynamicContainer[]::new);
|
||||
}
|
||||
|
||||
@WithAccessId(user = INSIDE_DYNAMIC_TEST_USER)
|
||||
@TestFactory
|
||||
DynamicContainer[] should_SetAccessIdForDynamicContainerInArray_When_AnnotationExists() {
|
||||
Supplier<DynamicContainer> supplier =
|
||||
() ->
|
||||
dynamicContainer(
|
||||
"dynamic container",
|
||||
Stream.of(DYNAMIC_TEST_USER_DYNAMIC_TEST, DYNAMIC_TEST_USER_DYNAMIC_TEST));
|
||||
return Stream.generate(supplier).limit(2).toArray(DynamicContainer[]::new);
|
||||
}
|
||||
|
||||
@WithAccessId(user = INSIDE_DYNAMIC_TEST_USER)
|
||||
@WithAccessId(user = INSIDE_DYNAMIC_TEST_USER)
|
||||
@TestFactory
|
||||
DynamicContainer[] should_SetMultipleAccessIdForDynamicContainerInArray_When_AnnotationsExist() {
|
||||
Supplier<DynamicContainer> supplier =
|
||||
() ->
|
||||
dynamicContainer(
|
||||
"dynamic container", Stream.of(NOT_NULL_DYNAMIC_TEST, NOT_NULL_DYNAMIC_TEST));
|
||||
return Stream.generate(supplier).limit(2).toArray(DynamicContainer[]::new);
|
||||
}
|
||||
|
||||
// WITH nested DynamicContainer
|
||||
|
||||
@TestFactory
|
||||
DynamicContainer[]
|
||||
should_NotSetAccessIdForNestedDynamicContainerInArray_When_AnnotationIsMissing() {
|
||||
Supplier<DynamicContainer> supplier =
|
||||
() -> dynamicContainer("inside container", Stream.of(NULL_DYNAMIC_TEST, NULL_DYNAMIC_TEST));
|
||||
Supplier<DynamicContainer> outsideSupplier =
|
||||
() -> dynamicContainer("outside container", Stream.of(supplier.get(), NULL_DYNAMIC_TEST));
|
||||
return Stream.generate(outsideSupplier).limit(2).toArray(DynamicContainer[]::new);
|
||||
}
|
||||
|
||||
@WithAccessId(user = INSIDE_DYNAMIC_TEST_USER)
|
||||
@TestFactory
|
||||
DynamicContainer[] should_SetAccessIdForNestedDynamicContainerInArray_When_AnnotationExists() {
|
||||
Supplier<DynamicContainer> supplier =
|
||||
() ->
|
||||
dynamicContainer(
|
||||
"inside container",
|
||||
Stream.of(DYNAMIC_TEST_USER_DYNAMIC_TEST, DYNAMIC_TEST_USER_DYNAMIC_TEST));
|
||||
Supplier<DynamicContainer> outsideSupplier =
|
||||
() ->
|
||||
dynamicContainer(
|
||||
"outside container", Stream.of(supplier.get(), DYNAMIC_TEST_USER_DYNAMIC_TEST));
|
||||
return Stream.generate(outsideSupplier).limit(2).toArray(DynamicContainer[]::new);
|
||||
}
|
||||
|
||||
@WithAccessId(user = INSIDE_DYNAMIC_TEST_USER)
|
||||
@WithAccessId(user = INSIDE_DYNAMIC_TEST_USER)
|
||||
@TestFactory
|
||||
DynamicContainer[]
|
||||
should_SetMultipleAccessIdForNestedDynamicContainerInArray_When_AnnotationsExist() {
|
||||
Supplier<DynamicContainer> supplier =
|
||||
() ->
|
||||
dynamicContainer(
|
||||
"inside container", Stream.of(NOT_NULL_DYNAMIC_TEST, NOT_NULL_DYNAMIC_TEST));
|
||||
Supplier<DynamicContainer> outsideSupplier =
|
||||
() ->
|
||||
dynamicContainer("outside container", Stream.of(supplier.get(), NOT_NULL_DYNAMIC_TEST));
|
||||
return Stream.generate(outsideSupplier).limit(2).toArray(DynamicContainer[]::new);
|
||||
}
|
||||
|
||||
// endregion
|
||||
|
||||
// region JaasExtension#interceptTestClassConstructor
|
||||
|
||||
@Nested
|
||||
@TestInstance(Lifecycle.PER_CLASS)
|
||||
class ConstructorWithoutAccessId {
|
||||
ConstructorWithoutAccessId() {
|
||||
assertThat(CURRENT_USER_CONTEXT.getUserid()).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
void should_NotSetJaasSubject_When_AnnotationIsMissing_On_Constructor() {
|
||||
assertThat(CURRENT_USER_CONTEXT.getUserid()).isNull();
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
@TestInstance(Lifecycle.PER_CLASS)
|
||||
class ConstructorWithAccessId {
|
||||
@WithAccessId(user = "constructor")
|
||||
ConstructorWithAccessId() {
|
||||
assertThat(CURRENT_USER_CONTEXT.getUserid()).isEqualTo("constructor");
|
||||
}
|
||||
|
||||
@Test
|
||||
void should_SetJaasSubject_When_AnnotationExists_On_Constructor() {
|
||||
assertThat(CURRENT_USER_CONTEXT.getUserid()).isNull();
|
||||
}
|
||||
}
|
||||
|
||||
// endregion
|
||||
|
||||
// endregion
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
package pro.taskana.testapi.tests.security;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
import org.junit.jupiter.api.extension.ExtensionContext;
|
||||
import org.junit.jupiter.api.extension.ParameterResolutionException;
|
||||
import org.junit.jupiter.api.extension.TestExecutionExceptionHandler;
|
||||
import org.junit.platform.commons.JUnitException;
|
||||
|
||||
public class JaasExtensionTestExtensions {
|
||||
static class ShouldThrowParameterResolutionException implements TestExecutionExceptionHandler {
|
||||
|
||||
@Override
|
||||
public void handleTestExecutionException(ExtensionContext context, Throwable throwable)
|
||||
throws Throwable {
|
||||
if (throwable instanceof ParameterResolutionException) {
|
||||
return;
|
||||
}
|
||||
throw throwable;
|
||||
}
|
||||
}
|
||||
|
||||
static class ShouldThrowJunitException implements TestExecutionExceptionHandler {
|
||||
|
||||
@Override
|
||||
public void handleTestExecutionException(ExtensionContext context, Throwable throwable)
|
||||
throws Throwable {
|
||||
if (throwable instanceof JUnitException) {
|
||||
JUnitException exception = (JUnitException) throwable;
|
||||
assertThat(exception.getMessage())
|
||||
.isEqualTo("Please use @TestTemplate instead of @Test for multiple accessIds");
|
||||
return;
|
||||
}
|
||||
throw throwable;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
taskana/db2:11.5
|
|
@ -0,0 +1,35 @@
|
|||
# SLF4J's SimpleLogger configuration file
|
||||
# Simple implementation of Logger that sends all enabled log messages, for all defined loggers, to System.err.
|
||||
|
||||
# Default logging detail level for all instances of SimpleLogger.
|
||||
# Must be one of ("trace", "debug", "info", "warn", or "error").
|
||||
# If not specified, defaults to "info".
|
||||
org.slf4j.simpleLogger.defaultLogLevel=info
|
||||
|
||||
# Logging detail level for a SimpleLogger instance named "xxxxx".
|
||||
# Must be one of ("trace", "debug", "info", "warn", or "error").
|
||||
# If not specified, the default logging detail level is used.
|
||||
org.slf4j.simpleLogger.log.pro.taskana=info
|
||||
org.slf4j.simpleLogger.log.org.apache.ibatis=info
|
||||
|
||||
# Set to true if you want the current date and time to be included in output messages.
|
||||
# Default is false, and will output the number of milliseconds elapsed since startup.
|
||||
org.slf4j.simpleLogger.showDateTime=true
|
||||
|
||||
# The date and time format to be used in the output messages.
|
||||
# The pattern describing the date and time format is the same that is used in java.text.SimpleDateFormat.
|
||||
# If the format is not specified or is invalid, the default format is used.
|
||||
# The default format is yyyy-MM-dd HH:mm:ss:SSS Z.
|
||||
org.slf4j.simpleLogger.dateTimeFormat=yyyy-MM-dd HH:mm:ss:SSS Z
|
||||
|
||||
# Set to true if you want to output the current thread name.
|
||||
# Defaults to true.
|
||||
org.slf4j.simpleLogger.showThreadName=true
|
||||
|
||||
# Set to true if you want the Logger instance name to be included in output messages.
|
||||
# Defaults to true.
|
||||
#org.slf4j.simpleLogger.showLogName=true
|
||||
|
||||
# Set to true if you want the last component of the name to be included in output messages.
|
||||
# Defaults to false.
|
||||
org.slf4j.simpleLogger.showShortLogName=false
|
|
@ -0,0 +1,20 @@
|
|||
taskana.roles.user=cn=ksc-users,cn=groups,OU=Test,O=TASKANA | teamlead-1 | teamlead-2 | user-1-1 | user-1-2 | user-2-1 | user-2-2 | user-b-1 | user-b-2
|
||||
taskana.roles.admin=admin | uid=admin,cn=users,OU=Test,O=TASKANA
|
||||
taskana.roles.businessadmin=businessadmin | cn=business-admins,cn=groups,OU=Test,O=TASKANA
|
||||
taskana.roles.monitor=monitor | cn=monitor-users,cn=groups,OU=Test,O=TASKANA
|
||||
taskana.roles.taskadmin=taskadmin
|
||||
taskana.domains=Domain_A , DOMAIN_B
|
||||
taskana.classification.types=TASK , document
|
||||
taskana.classification.categories.task=EXTERNAL, manual, autoMAtic, Process
|
||||
taskana.classification.categories.document=EXTERNAL
|
||||
taskana.jobs.maxRetries=3
|
||||
taskana.jobs.batchSize=50
|
||||
taskana.jobs.cleanup.runEvery=P1D
|
||||
taskana.jobs.cleanup.firstRunAt=2018-07-25T08:00:00Z
|
||||
taskana.jobs.cleanup.minimumAge=P14D
|
||||
taskana.german.holidays.enabled=true
|
||||
taskana.german.holidays.corpus-christi.enabled=false
|
||||
taskana.history.deletion.on.task.deletion.enabled=true
|
||||
taskana.validation.allowTimestampServiceLevelMismatch=false
|
||||
taskana.query.includeLongName=false
|
||||
|
Loading…
Reference in New Issue