diff --git a/common/taskana-common-test/src/main/java/pro/taskana/common/test/config/TaskanaEngineTestConfiguration.java b/common/taskana-common-test/src/main/java/pro/taskana/common/test/config/DataSourceGenerator.java similarity index 58% rename from common/taskana-common-test/src/main/java/pro/taskana/common/test/config/TaskanaEngineTestConfiguration.java rename to common/taskana-common-test/src/main/java/pro/taskana/common/test/config/DataSourceGenerator.java index a19366953..8e88f270c 100644 --- a/common/taskana-common-test/src/main/java/pro/taskana/common/test/config/TaskanaEngineTestConfiguration.java +++ b/common/taskana-common-test/src/main/java/pro/taskana/common/test/config/DataSourceGenerator.java @@ -10,72 +10,49 @@ import org.apache.ibatis.datasource.pooled.PooledDataSource; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -/** Integration Test for TaskanaEngineConfiguration. */ -public final class TaskanaEngineTestConfiguration { +/** + * The DataSourceGenerator provides the proper {@linkplain DataSource} for all Integration tests. + * + *

If the file ${user.home}/taskanaUnitTest.properties is present, the {@linkplain + * DataSource} is created according to the properties jdbcDriver, jdbcUrl, dbUserName and + * dbPassword. If any of these properties is missing, or the file doesn't exist, the default + * {@linkplain DataSource} for H2 in-memory db is created. + * + *

Additionally the property schemaName can be defined. If that property is missing, or + * the file doesn't exist the schemaName TASKANA will be used. + */ +public final class DataSourceGenerator { - private static final Logger LOGGER = - LoggerFactory.getLogger(TaskanaEngineTestConfiguration.class); - private static final int POOL_TIME_TO_WAIT = 50; + private static final Logger LOGGER = LoggerFactory.getLogger(DataSourceGenerator.class); private static final DataSource DATA_SOURCE; - private static String schemaName = null; + private static final String SCHEMA_NAME; + + private static final String DEFAULT_SCHEMA_NAME = "TASKANA"; + private static final int POOL_TIME_TO_WAIT = 50; static { String propertiesFileName = System.getProperty("user.home") + "/taskanaUnitTest.properties"; File f = new File(propertiesFileName); if (f.exists() && !f.isDirectory()) { DATA_SOURCE = createDataSourceFromProperties(propertiesFileName); + SCHEMA_NAME = getSchemaNameFromPropertiesObject(propertiesFileName); } else { - DATA_SOURCE = createDefaultDataSource(); + DATA_SOURCE = createDataSourceForH2(); + SCHEMA_NAME = DEFAULT_SCHEMA_NAME; } } - private TaskanaEngineTestConfiguration() {} + private DataSourceGenerator() {} - /** - * returns the Datasource used for Junit test. If the file {user.home}/taskanaUnitTest.properties - * is present, the Datasource is created according to the properties jdbcDriver, jdbcUrl, - * dbUserName and dbPassword. Assuming, the database has the name tskdb, a sample properties file - * for DB2 looks as follows: jdbcDriver=com.ibm.db2.jcc.DB2Driver - * jdbcUrl=jdbc:db2://localhost:50000/tskdb dbUserName=db2user dbPassword=db2password If any of - * these properties is missing, or the file doesn't exist, the default Datasource for h2 in-memory - * db is created. - * - * @return dataSource for unit test - */ public static DataSource getDataSource() { return DATA_SOURCE; } - /** - * returns the SchemaName used for Junit test. If the file {user.home}/taskanaUnitTest.properties - * is present, the SchemaName is created according to the property schemaName. a sample properties - * file for DB2 looks as follows: jdbcDriver=com.ibm.db2.jcc.DB2Driver - * jdbcUrl=jdbc:db2://localhost:50000/tskdb dbUserName=db2user dbPassword=db2password - * schemaName=TASKANA If any of these properties is missing, or the file doesn't exist, the - * default schemaName TASKANA is created used. - * - * @return String for unit test - */ public static String getSchemaName() { - if (schemaName == null) { - String propertiesFileName = System.getProperty("user.home") + "/taskanaUnitTest.properties"; - File f = new File(propertiesFileName); - if (f.exists() && !f.isDirectory()) { - schemaName = getSchemaNameFromPropertiesObject(propertiesFileName); - } else { - schemaName = "TASKANA"; - } - } - return schemaName; + return SCHEMA_NAME; } - /** - * create data source from properties file. - * - * @param propertiesFileName the name of the property file - * @return the parsed datasource. - */ - public static DataSource createDataSourceFromProperties(String propertiesFileName) { + private static DataSource createDataSourceFromProperties(String propertiesFileName) { DataSource ds; try (InputStream input = new FileInputStream(propertiesFileName)) { Properties prop = new Properties(); @@ -112,24 +89,24 @@ public final class TaskanaEngineTestConfiguration { dbUserName, dbPassword); ((PooledDataSource) ds) - .forceCloseAll(); // otherwise the MyBatis pool is not initialized correctly + .forceCloseAll(); // otherwise, the MyBatis pool is not initialized correctly } else { LOGGER.warn("propertiesFile {} is incomplete {}", propertiesFileName, warningMessage); LOGGER.warn("Using default Datasource for Test"); - ds = createDefaultDataSource(); + ds = createDataSourceForH2(); } } catch (IOException e) { LOGGER.warn("createDataSourceFromProperties caught Exception ", e); LOGGER.warn("Using default Datasource for Test"); - ds = createDefaultDataSource(); + ds = createDataSourceForH2(); } return ds; } - static String getSchemaNameFromPropertiesObject(String propertiesFileName) { - String schemaName = "TASKANA"; + private static String getSchemaNameFromPropertiesObject(String propertiesFileName) { + String schemaName = DEFAULT_SCHEMA_NAME; try (InputStream input = new FileInputStream(propertiesFileName)) { Properties prop = new Properties(); prop.load(input); @@ -144,21 +121,21 @@ public final class TaskanaEngineTestConfiguration { if (!propertiesFileIsComplete) { LOGGER.warn("propertiesFile {} is incomplete {}", propertiesFileName, warningMessage); LOGGER.warn("Using default Datasource for Test"); - schemaName = "TASKANA"; + schemaName = DEFAULT_SCHEMA_NAME; } - } catch (Exception e) { - LOGGER.warn("Caught Exception ", e); + } catch (IOException e) { + LOGGER.warn("getSchemaNameFromPropertiesObject caught Exception ", e); LOGGER.warn("Using default schemaName for Test"); } return schemaName; } - private static DataSource createDefaultDataSource() { + private static DataSource createDataSourceForH2() { String jdbcDriver = "org.h2.Driver"; String jdbcUrl = - "jdbc:h2:mem:taskana;IGNORECASE=TRUE;LOCK_MODE=0;" + "jdbc:h2:mem:taskana;LOCK_MODE=0;" + "INIT=CREATE SCHEMA IF NOT EXISTS TASKANA\\;" + "SET COLLATION DEFAULT_de_DE "; String dbUserName = "sa"; @@ -171,7 +148,7 @@ public final class TaskanaEngineTestConfiguration { dbUserName, dbPassword); ds.setPoolTimeToWait(POOL_TIME_TO_WAIT); - ds.forceCloseAll(); // otherwise the MyBatis pool is not initialized correctly + ds.forceCloseAll(); // otherwise, the MyBatis pool is not initialized correctly return ds; } diff --git a/common/taskana-common-test/src/main/java/pro/taskana/common/test/security/JaasExtension.java b/common/taskana-common-test/src/main/java/pro/taskana/common/test/security/JaasExtension.java index 65d4d43f8..a8d67fb86 100644 --- a/common/taskana-common-test/src/main/java/pro/taskana/common/test/security/JaasExtension.java +++ b/common/taskana-common-test/src/main/java/pro/taskana/common/test/security/JaasExtension.java @@ -125,7 +125,7 @@ public class JaasExtension implements InvocationInterceptor, TestTemplateInvocat invocationContext.getExecutable().getName())); } - // Currently a DynamicContainer has children from this type: Stream + // Currently, a DynamicContainer has children from this type: Stream // 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... diff --git a/common/taskana-common/src/main/java/pro/taskana/common/internal/util/CheckedBiConsumer.java b/common/taskana-common/src/main/java/pro/taskana/common/internal/util/CheckedBiConsumer.java deleted file mode 100644 index 334c4ae12..000000000 --- a/common/taskana-common/src/main/java/pro/taskana/common/internal/util/CheckedBiConsumer.java +++ /dev/null @@ -1,7 +0,0 @@ -package pro.taskana.common.internal.util; - -@FunctionalInterface -public interface CheckedBiConsumer { - - void accept(T t, U u) throws E; -} diff --git a/common/taskana-common/src/main/java/pro/taskana/common/internal/util/CheckedConsumer.java b/common/taskana-common/src/main/java/pro/taskana/common/internal/util/CheckedConsumer.java index afa69edb6..f1ab28b00 100644 --- a/common/taskana-common/src/main/java/pro/taskana/common/internal/util/CheckedConsumer.java +++ b/common/taskana-common/src/main/java/pro/taskana/common/internal/util/CheckedConsumer.java @@ -6,7 +6,7 @@ import pro.taskana.common.api.exceptions.SystemException; @FunctionalInterface public interface CheckedConsumer { - static Consumer wrap(CheckedConsumer checkedConsumer) { + static Consumer wrap(CheckedConsumer checkedConsumer) { return t -> { try { checkedConsumer.accept(t); diff --git a/common/taskana-common/src/main/java/pro/taskana/common/internal/util/CheckedFunction.java b/common/taskana-common/src/main/java/pro/taskana/common/internal/util/CheckedFunction.java index a19338739..f464e49a5 100644 --- a/common/taskana-common/src/main/java/pro/taskana/common/internal/util/CheckedFunction.java +++ b/common/taskana-common/src/main/java/pro/taskana/common/internal/util/CheckedFunction.java @@ -5,8 +5,8 @@ import java.util.function.Function; import pro.taskana.common.api.exceptions.SystemException; @FunctionalInterface -public interface CheckedFunction { - static Function wrap(CheckedFunction checkedFunction) { +public interface CheckedFunction { + static Function wrap(CheckedFunction checkedFunction) { return t -> { try { return checkedFunction.apply(t); @@ -16,8 +16,8 @@ public interface CheckedFunction { }; } - static Function wrapExceptFor( - CheckedFunction checkedFunction, Class ignore) { + static Function wrapExceptFor( + CheckedFunction checkedFunction, Class ignore) { return t -> { try { return checkedFunction.apply(t); @@ -31,5 +31,5 @@ public interface CheckedFunction { }; } - E apply(T t) throws Throwable; + R apply(T t) throws E; } diff --git a/common/taskana-common/src/main/java/pro/taskana/common/internal/util/CheckedSupplier.java b/common/taskana-common/src/main/java/pro/taskana/common/internal/util/CheckedSupplier.java new file mode 100644 index 000000000..4748c6cc2 --- /dev/null +++ b/common/taskana-common/src/main/java/pro/taskana/common/internal/util/CheckedSupplier.java @@ -0,0 +1,21 @@ +package pro.taskana.common.internal.util; + +import java.util.function.Supplier; + +import pro.taskana.common.api.exceptions.SystemException; + +@FunctionalInterface +public interface CheckedSupplier { + + static Supplier wrap(CheckedSupplier checkedSupplier) { + return () -> { + try { + return checkedSupplier.get(); + } catch (Throwable e) { + throw new SystemException("Caught exception", e); + } + }; + } + + T get() throws E; +} diff --git a/common/taskana-common/src/main/java/pro/taskana/common/internal/util/Quadruple.java b/common/taskana-common/src/main/java/pro/taskana/common/internal/util/Quadruple.java new file mode 100644 index 000000000..c8b57d389 --- /dev/null +++ b/common/taskana-common/src/main/java/pro/taskana/common/internal/util/Quadruple.java @@ -0,0 +1,36 @@ +package pro.taskana.common.internal.util; + +public class Quadruple { + + private final A first; + private final S second; + private final D third; + private final F fourth; + + private Quadruple(A first, S second, D third, F fourth) { + this.first = first; + this.second = second; + this.third = third; + this.fourth = fourth; + } + + public static Quadruple of(A a, S s, D d, F f) { + return new Quadruple<>(a, s, d, f); + } + + public A getFirst() { + return first; + } + + public S getSecond() { + return second; + } + + public D getThird() { + return third; + } + + public F getFourth() { + return fourth; + } +} diff --git a/lib/taskana-core/src/main/java/pro/taskana/TaskanaEngineConfiguration.java b/lib/taskana-core/src/main/java/pro/taskana/TaskanaEngineConfiguration.java index 96e04fd6b..51d5b0559 100644 --- a/lib/taskana-core/src/main/java/pro/taskana/TaskanaEngineConfiguration.java +++ b/lib/taskana-core/src/main/java/pro/taskana/TaskanaEngineConfiguration.java @@ -430,12 +430,12 @@ public class TaskanaEngineConfiguration { } private Optional parseProperty( - Properties props, String key, CheckedFunction function) { + Properties props, String key, CheckedFunction function) { String property = props.getProperty(key, ""); if (!property.isEmpty()) { try { return Optional.ofNullable(function.apply(property)); - } catch (Throwable t) { + } catch (Exception t) { LOGGER.warn( "Could not parse property {} ({}). Using default. Exception: {}", key, @@ -498,7 +498,7 @@ public class TaskanaEngineConfiguration { } private void initDomains(Properties props) { - CheckedFunction> parseFunction = + CheckedFunction, Exception> parseFunction = p -> splitStringAndTrimElements(p, ",", String::toUpperCase); parseProperty(props, TASKANA_DOMAINS_PROPERTY, parseFunction).ifPresent(this::setDomains); @@ -508,7 +508,7 @@ public class TaskanaEngineConfiguration { } private void initClassificationTypes(Properties props) { - CheckedFunction> parseFunction = + CheckedFunction, Exception> parseFunction = p -> splitStringAndTrimElements(p, ",", String::toUpperCase); parseProperty(props, TASKANA_CLASSIFICATION_TYPES_PROPERTY, parseFunction) .ifPresent(this::setClassificationTypes); @@ -521,7 +521,7 @@ public class TaskanaEngineConfiguration { private void initClassificationCategories(Properties props) { Function> getClassificationCategoriesForType = type -> { - CheckedFunction> parseFunction = + CheckedFunction, Exception> parseFunction = s -> splitStringAndTrimElements(s, ",", String::toUpperCase); return parseProperty( props, @@ -593,7 +593,7 @@ public class TaskanaEngineConfiguration { } private void initCustomHolidays(Properties props, String separator) { - CheckedFunction> parseFunction = + CheckedFunction, Exception> parseFunction = s -> splitStringAndTrimElements(s, separator).stream() .map( diff --git a/lib/taskana-core/src/main/java/pro/taskana/classification/internal/ClassificationBuilder.java b/lib/taskana-core/src/main/java/pro/taskana/classification/internal/ClassificationBuilder.java new file mode 100644 index 000000000..84e3ce930 --- /dev/null +++ b/lib/taskana-core/src/main/java/pro/taskana/classification/internal/ClassificationBuilder.java @@ -0,0 +1,135 @@ +package pro.taskana.classification.internal; + +import java.security.PrivilegedActionException; +import java.security.PrivilegedExceptionAction; +import java.time.Instant; +import javax.security.auth.Subject; + +import pro.taskana.classification.api.ClassificationCustomField; +import pro.taskana.classification.api.ClassificationService; +import pro.taskana.classification.api.exceptions.ClassificationAlreadyExistException; +import pro.taskana.classification.api.exceptions.ClassificationNotFoundException; +import pro.taskana.classification.api.exceptions.MalformedServiceLevelException; +import pro.taskana.classification.api.models.Classification; +import pro.taskana.common.api.exceptions.DomainNotFoundException; +import pro.taskana.common.api.exceptions.InvalidArgumentException; +import pro.taskana.common.api.exceptions.NotAuthorizedException; +import pro.taskana.common.api.security.UserPrincipal; + +public class ClassificationBuilder { + + private final ClassificationTestImpl testClassification = new ClassificationTestImpl(); + + private ClassificationBuilder() {} + + public static ClassificationBuilder newClassification() { + return new ClassificationBuilder(); + } + + public ClassificationBuilder applicationEntryPoint(String applicationEntryPoint) { + testClassification.setApplicationEntryPoint(applicationEntryPoint); + return this; + } + + public ClassificationBuilder category(String category) { + testClassification.setCategory(category); + return this; + } + + public ClassificationBuilder domain(String domain) { + testClassification.setDomain(domain); + return this; + } + + public ClassificationBuilder key(String key) { + testClassification.setKey(key); + return this; + } + + public ClassificationBuilder name(String name) { + testClassification.setName(name); + return this; + } + + public ClassificationBuilder parentId(String parentId) { + testClassification.setParentId(parentId); + return this; + } + + public ClassificationBuilder parentKey(String parentKey) { + testClassification.setParentKey(parentKey); + return this; + } + + public ClassificationBuilder priority(int priority) { + testClassification.setPriority(priority); + return this; + } + + public ClassificationBuilder serviceLevel(String serviceLevel) { + testClassification.setServiceLevel(serviceLevel); + return this; + } + + public ClassificationBuilder type(String type) { + testClassification.setType(type); + return this; + } + + public ClassificationBuilder customAttribute( + ClassificationCustomField customField, String value) { + testClassification.setCustomAttribute(customField, value); + return this; + } + + public ClassificationBuilder isValidInDomain(boolean isValidInDomain) { + testClassification.setIsValidInDomain(isValidInDomain); + return this; + } + + public ClassificationBuilder created(Instant created) { + testClassification.setCreatedIgnoreFreeze(created); + if (created != null) { + testClassification.freezeCreated(); + } else { + testClassification.unfreezeCreated(); + } + return this; + } + + public ClassificationBuilder modified(Instant modified) { + testClassification.setModifiedIgnoreFreeze(modified); + if (modified != null) { + testClassification.freezeModified(); + } else { + testClassification.unfreezeModified(); + } + return this; + } + + public ClassificationBuilder description(String description) { + testClassification.setDescription(description); + return this; + } + + public Classification buildAndStore(ClassificationService classificationService) + throws InvalidArgumentException, ClassificationAlreadyExistException, DomainNotFoundException, + MalformedServiceLevelException, NotAuthorizedException, ClassificationNotFoundException { + try { + Classification c = classificationService.createClassification(testClassification); + return classificationService.getClassification(c.getId()); + } finally { + testClassification.setId(null); + } + } + + public Classification buildAndStore(ClassificationService classificationService, String userId) + throws PrivilegedActionException { + Subject subject = new Subject(); + subject.getPrincipals().add(new UserPrincipal(userId)); + PrivilegedExceptionAction performBuildAndStore = + () -> buildAndStore(classificationService); + + return Subject.doAs(subject, performBuildAndStore); + } +} diff --git a/lib/taskana-core/src/main/java/pro/taskana/classification/internal/ClassificationServiceImpl.java b/lib/taskana-core/src/main/java/pro/taskana/classification/internal/ClassificationServiceImpl.java index 02da3aab8..f9a0d8411 100644 --- a/lib/taskana-core/src/main/java/pro/taskana/classification/internal/ClassificationServiceImpl.java +++ b/lib/taskana-core/src/main/java/pro/taskana/classification/internal/ClassificationServiceImpl.java @@ -350,7 +350,7 @@ public class ClassificationServiceImpl implements ClassificationService { private void checkClassificationId(ClassificationImpl classificationImpl) throws InvalidArgumentException { - if (classificationImpl.getId() != null && !"".equals(classificationImpl.getId())) { + if (classificationImpl.getId() != null && !classificationImpl.getId().isEmpty()) { throw new InvalidArgumentException("ClassificationId should be null on creation"); } } @@ -365,7 +365,7 @@ public class ClassificationServiceImpl implements ClassificationService { masterClassification.setDomain(""); masterClassification.setIsValidInDomain(false); try { - if (classification.getParentKey() != null && !"".equals(classification.getParentKey())) { + if (classification.getParentKey() != null && !classification.getParentKey().isEmpty()) { masterClassification.setParentId( getClassification(classification.getParentKey(), "").getId()); } @@ -410,7 +410,7 @@ public class ClassificationServiceImpl implements ClassificationService { private void initDefaultClassificationValues(ClassificationImpl classification) throws InvalidArgumentException, MalformedServiceLevelException { Instant now = Instant.now(); - if (classification.getId() == null || "".equals(classification.getId())) { + if (classification.getId() == null || classification.getId().isEmpty()) { classification.setId(IdGenerator.generateWithPrefix(IdGenerator.ID_PREFIX_CLASSIFICATION)); } diff --git a/lib/taskana-core/src/main/java/pro/taskana/classification/internal/ClassificationTestImpl.java b/lib/taskana-core/src/main/java/pro/taskana/classification/internal/ClassificationTestImpl.java new file mode 100644 index 000000000..a4cfbb01f --- /dev/null +++ b/lib/taskana-core/src/main/java/pro/taskana/classification/internal/ClassificationTestImpl.java @@ -0,0 +1,49 @@ +package pro.taskana.classification.internal; + +import java.time.Instant; + +import pro.taskana.classification.internal.models.ClassificationImpl; + +class ClassificationTestImpl extends ClassificationImpl { + + private boolean freezeCreated = false; + private boolean freezeModified = false; + + @Override + public void setCreated(Instant created) { + if (!freezeCreated) { + super.setCreated(created); + } + } + + public void setCreatedIgnoreFreeze(Instant created) { + super.setCreated(created); + } + + @Override + public void setModified(Instant modified) { + if (!freezeModified) { + super.setModified(modified); + } + } + + public void setModifiedIgnoreFreeze(Instant modified) { + super.setModified(modified); + } + + public void freezeCreated() { + freezeCreated = true; + } + + public void unfreezeCreated() { + freezeCreated = false; + } + + public void freezeModified() { + freezeModified = true; + } + + public void unfreezeModified() { + freezeModified = false; + } +} diff --git a/lib/taskana-core/src/main/java/pro/taskana/task/internal/AttachmentHandler.java b/lib/taskana-core/src/main/java/pro/taskana/task/internal/AttachmentHandler.java index a645ae187..a966955bf 100644 --- a/lib/taskana-core/src/main/java/pro/taskana/task/internal/AttachmentHandler.java +++ b/lib/taskana-core/src/main/java/pro/taskana/task/internal/AttachmentHandler.java @@ -162,15 +162,15 @@ public class AttachmentHandler { if (attachment.getId() == null) { attachment.setId(IdGenerator.generateWithPrefix(IdGenerator.ID_PREFIX_ATTACHMENT)); } + if (attachment.getTaskId() == null) { + attachment.setTaskId(newTask.getId()); + } if (attachment.getCreated() == null) { attachment.setCreated(newTask.getModified()); } if (attachment.getModified() == null) { attachment.setModified(attachment.getCreated()); } - if (attachment.getTaskId() == null) { - attachment.setTaskId(newTask.getId()); - } } private void verifyAttachment(AttachmentImpl attachment, String domain) diff --git a/lib/taskana-core/src/main/java/pro/taskana/task/internal/ObjectReferenceBuilder.java b/lib/taskana-core/src/main/java/pro/taskana/task/internal/ObjectReferenceBuilder.java new file mode 100644 index 000000000..94c0ff392 --- /dev/null +++ b/lib/taskana-core/src/main/java/pro/taskana/task/internal/ObjectReferenceBuilder.java @@ -0,0 +1,43 @@ +package pro.taskana.task.internal; + +import pro.taskana.task.api.models.ObjectReference; + +public class ObjectReferenceBuilder { + + private final ObjectReference objectReference = new ObjectReference(); + + private ObjectReferenceBuilder() {} + + public static ObjectReferenceBuilder newObjectReference() { + return new ObjectReferenceBuilder(); + } + + public ObjectReferenceBuilder company(String company) { + objectReference.setCompany(company); + return this; + } + + public ObjectReferenceBuilder system(String system) { + objectReference.setSystem(system); + return this; + } + + public ObjectReferenceBuilder systemInstance(String systemInstance) { + objectReference.setSystemInstance(systemInstance); + return this; + } + + public ObjectReferenceBuilder type(String type) { + objectReference.setType(type); + return this; + } + + public ObjectReferenceBuilder value(String value) { + objectReference.setValue(value); + return this; + } + + public ObjectReference build() { + return objectReference.copy(); + } +} diff --git a/lib/taskana-core/src/main/java/pro/taskana/task/internal/TaskAttachmentBuilder.java b/lib/taskana-core/src/main/java/pro/taskana/task/internal/TaskAttachmentBuilder.java new file mode 100644 index 000000000..271981f75 --- /dev/null +++ b/lib/taskana-core/src/main/java/pro/taskana/task/internal/TaskAttachmentBuilder.java @@ -0,0 +1,59 @@ +package pro.taskana.task.internal; + +import java.time.Instant; +import java.util.Map; + +import pro.taskana.classification.api.models.ClassificationSummary; +import pro.taskana.task.api.models.Attachment; +import pro.taskana.task.api.models.ObjectReference; +import pro.taskana.task.internal.models.AttachmentImpl; + +public class TaskAttachmentBuilder { + + private final AttachmentImpl attachment = new AttachmentImpl(); + + public static TaskAttachmentBuilder newAttachment() { + return new TaskAttachmentBuilder(); + } + + public TaskAttachmentBuilder created(Instant created) { + attachment.setCreated(created); + return this; + } + + public TaskAttachmentBuilder modified(Instant modified) { + attachment.setModified(modified); + return this; + } + + public TaskAttachmentBuilder received(Instant received) { + attachment.setReceived(received); + return this; + } + + public TaskAttachmentBuilder classificationSummary(ClassificationSummary classificationSummary) { + attachment.setClassificationSummary(classificationSummary); + return this; + } + + public TaskAttachmentBuilder objectReference(ObjectReference objectReference) { + attachment.setObjectReference(objectReference); + return this; + } + + public TaskAttachmentBuilder channel(String channel) { + attachment.setChannel(channel); + return this; + } + + public TaskAttachmentBuilder customAttributes(Map customAttributes) { + attachment.setCustomAttributes(customAttributes); + return this; + } + + public Attachment build() { + AttachmentImpl a = attachment.copy(); + a.setTaskId(attachment.getTaskId()); + return a; + } +} diff --git a/lib/taskana-core/src/main/java/pro/taskana/task/internal/TaskCommentBuilder.java b/lib/taskana-core/src/main/java/pro/taskana/task/internal/TaskCommentBuilder.java new file mode 100644 index 000000000..48f95cdf7 --- /dev/null +++ b/lib/taskana-core/src/main/java/pro/taskana/task/internal/TaskCommentBuilder.java @@ -0,0 +1,73 @@ +package pro.taskana.task.internal; + +import java.security.PrivilegedActionException; +import java.security.PrivilegedExceptionAction; +import java.time.Instant; +import javax.security.auth.Subject; + +import pro.taskana.common.api.exceptions.InvalidArgumentException; +import pro.taskana.common.api.exceptions.NotAuthorizedException; +import pro.taskana.common.api.security.UserPrincipal; +import pro.taskana.task.api.TaskService; +import pro.taskana.task.api.exceptions.TaskCommentNotFoundException; +import pro.taskana.task.api.exceptions.TaskNotFoundException; +import pro.taskana.task.api.models.TaskComment; + +public class TaskCommentBuilder { + + private final TaskCommentTestImpl testTaskComment = new TaskCommentTestImpl(); + + public static TaskCommentBuilder newTaskComment() { + return new TaskCommentBuilder(); + } + + public TaskCommentBuilder taskId(String taskId) { + testTaskComment.setTaskId(taskId); + return this; + } + + public TaskCommentBuilder textField(String textField) { + testTaskComment.setTextField(textField); + return this; + } + + public TaskCommentBuilder created(Instant created) { + testTaskComment.setCreatedIgnoringFreeze(created); + if (created != null) { + testTaskComment.freezeCreated(); + } else { + testTaskComment.unfreezeCreated(); + } + return this; + } + + public TaskCommentBuilder modified(Instant modified) { + testTaskComment.setModifiedIgnoringFreeze(modified); + if (modified != null) { + testTaskComment.freezeModified(); + } else { + testTaskComment.unfreezeModified(); + } + return this; + } + + public TaskComment buildAndStore(TaskService taskService) + throws InvalidArgumentException, TaskNotFoundException, NotAuthorizedException, + TaskCommentNotFoundException { + try { + TaskComment t = taskService.createTaskComment(testTaskComment); + return taskService.getTaskComment(t.getId()); + } finally { + testTaskComment.setId(null); + } + } + + public TaskComment buildAndStore(TaskService taskService, String userId) + throws PrivilegedActionException { + Subject subject = new Subject(); + subject.getPrincipals().add(new UserPrincipal(userId)); + PrivilegedExceptionAction performBuildAndStore = () -> buildAndStore(taskService); + + return Subject.doAs(subject, performBuildAndStore); + } +} diff --git a/lib/taskana-core/src/main/java/pro/taskana/task/internal/TaskCommentTestImpl.java b/lib/taskana-core/src/main/java/pro/taskana/task/internal/TaskCommentTestImpl.java new file mode 100644 index 000000000..156e0c9a5 --- /dev/null +++ b/lib/taskana-core/src/main/java/pro/taskana/task/internal/TaskCommentTestImpl.java @@ -0,0 +1,49 @@ +package pro.taskana.task.internal; + +import java.time.Instant; + +import pro.taskana.task.internal.models.TaskCommentImpl; + +class TaskCommentTestImpl extends TaskCommentImpl { + + private boolean freezeCreated = false; + private boolean freezeModified = false; + + @Override + public void setCreated(Instant created) { + if (!freezeCreated) { + super.setCreated(created); + } + } + + public void setCreatedIgnoringFreeze(Instant created) { + super.setCreated(created); + } + + @Override + public void setModified(Instant modified) { + if (!freezeModified) { + super.setModified(modified); + } + } + + public void setModifiedIgnoringFreeze(Instant modified) { + super.setModified(modified); + } + + public void freezeCreated() { + freezeCreated = true; + } + + public void unfreezeCreated() { + freezeCreated = false; + } + + public void freezeModified() { + freezeModified = true; + } + + public void unfreezeModified() { + freezeModified = false; + } +} diff --git a/lib/taskana-core/src/main/java/pro/taskana/task/internal/TaskServiceImpl.java b/lib/taskana-core/src/main/java/pro/taskana/task/internal/TaskServiceImpl.java index f67093918..c3435e1c7 100644 --- a/lib/taskana-core/src/main/java/pro/taskana/task/internal/TaskServiceImpl.java +++ b/lib/taskana-core/src/main/java/pro/taskana/task/internal/TaskServiceImpl.java @@ -188,7 +188,7 @@ public class TaskServiceImpl implements TaskService { } Workbasket workbasket; - if (task.getWorkbasketSummary().getId() != null) { + if (task.getWorkbasketSummary() != null && task.getWorkbasketSummary().getId() != null) { workbasket = workbasketService.getWorkbasket(task.getWorkbasketSummary().getId()); } else if (task.getWorkbasketKey() != null) { workbasket = workbasketService.getWorkbasket(task.getWorkbasketKey(), task.getDomain()); diff --git a/lib/taskana-core/src/main/java/pro/taskana/task/internal/builder/TaskBuilder.java b/lib/taskana-core/src/main/java/pro/taskana/task/internal/builder/TaskBuilder.java new file mode 100644 index 000000000..a2310517d --- /dev/null +++ b/lib/taskana-core/src/main/java/pro/taskana/task/internal/builder/TaskBuilder.java @@ -0,0 +1,206 @@ +package pro.taskana.task.internal.builder; + +import java.security.PrivilegedActionException; +import java.security.PrivilegedExceptionAction; +import java.time.Instant; +import java.util.Arrays; +import java.util.Map; +import javax.security.auth.Subject; + +import pro.taskana.classification.api.exceptions.ClassificationNotFoundException; +import pro.taskana.classification.api.models.ClassificationSummary; +import pro.taskana.common.api.exceptions.InvalidArgumentException; +import pro.taskana.common.api.exceptions.NotAuthorizedException; +import pro.taskana.common.api.security.UserPrincipal; +import pro.taskana.task.api.CallbackState; +import pro.taskana.task.api.TaskCustomField; +import pro.taskana.task.api.TaskService; +import pro.taskana.task.api.TaskState; +import pro.taskana.task.api.exceptions.AttachmentPersistenceException; +import pro.taskana.task.api.exceptions.TaskAlreadyExistException; +import pro.taskana.task.api.exceptions.TaskNotFoundException; +import pro.taskana.task.api.models.Attachment; +import pro.taskana.task.api.models.ObjectReference; +import pro.taskana.task.api.models.Task; +import pro.taskana.workbasket.api.exceptions.WorkbasketNotFoundException; +import pro.taskana.workbasket.api.models.WorkbasketSummary; + +public class TaskBuilder { + + private final TaskTestImpl testTask = new TaskTestImpl(); + + public static TaskBuilder newTask() { + return new TaskBuilder(); + } + + public TaskBuilder externalId(String externalId) { + testTask.setExternalId(externalId); + return this; + } + + public TaskBuilder created(Instant created) { + testTask.setCreatedIgnoreFreeze(created); + if (created != null) { + testTask.freezeCreated(); + } else { + testTask.unfreezeCreated(); + } + return this; + } + + public TaskBuilder claimed(Instant claimed) { + testTask.setClaimed(claimed); + return this; + } + + public TaskBuilder completed(Instant completed) { + testTask.setCompleted(completed); + return this; + } + + public TaskBuilder modified(Instant modified) { + testTask.setModifiedIgnoreFreeze(modified); + if (modified != null) { + testTask.freezeModified(); + } else { + testTask.unfreezeModified(); + } + return this; + } + + public TaskBuilder received(Instant received) { + testTask.setReceived(received); + return this; + } + + public TaskBuilder planned(Instant planned) { + testTask.setPlanned(planned); + return this; + } + + public TaskBuilder due(Instant due) { + testTask.setDue(due); + return this; + } + + public TaskBuilder name(String name) { + testTask.setName(name); + return this; + } + + public TaskBuilder note(String note) { + testTask.setNote(note); + return this; + } + + public TaskBuilder description(String description) { + testTask.setDescription(description); + return this; + } + + public TaskBuilder state(TaskState state) { + testTask.setStateIgnoreFreeze(state); + if (state != null) { + testTask.freezeState(); + } else { + testTask.unfreezeState(); + } + return this; + } + + public TaskBuilder classificationSummary(ClassificationSummary classificationSummary) { + testTask.setClassificationSummary(classificationSummary); + return this; + } + + public TaskBuilder workbasketSummary(WorkbasketSummary workbasketSummary) { + testTask.setWorkbasketSummary(workbasketSummary); + return this; + } + + public TaskBuilder businessProcessId(String businessProcessId) { + testTask.setBusinessProcessId(businessProcessId); + return this; + } + + public TaskBuilder parentBusinessProcessId(String parentBusinessProcessId) { + testTask.setParentBusinessProcessId(parentBusinessProcessId); + return this; + } + + public TaskBuilder owner(String owner) { + testTask.setOwner(owner); + return this; + } + + public TaskBuilder primaryObjRef(ObjectReference primaryObjRef) { + testTask.setPrimaryObjRef(primaryObjRef); + return this; + } + + public TaskBuilder read(Boolean read) { + if (read != null) { + testTask.setReadIgnoreFreeze(read); + if (read) { + testTask.freezeRead(); + } + } else { + testTask.unfreezeRead(); + } + return this; + } + + public TaskBuilder transferred(Boolean transferred) { + if (transferred != null) { + testTask.setTransferredIgnoreFreeze(transferred); + if (transferred) { + testTask.freezeTransferred(); + } + } else { + testTask.unfreezeTransferred(); + } + return this; + } + + public TaskBuilder attachments(Attachment... attachments) { + testTask.setAttachments(Arrays.asList(attachments)); + return this; + } + + public TaskBuilder customAttribute(TaskCustomField customField, String value) { + testTask.setCustomAttribute(customField, value); + return this; + } + + public TaskBuilder callbackInfo(Map callbackInfo) { + testTask.setCallbackInfo(callbackInfo); + return this; + } + + public TaskBuilder callbackState(CallbackState callbackState) { + testTask.setCallbackState(callbackState); + return this; + } + + public Task buildAndStore(TaskService taskService) + throws TaskAlreadyExistException, InvalidArgumentException, WorkbasketNotFoundException, + ClassificationNotFoundException, NotAuthorizedException, AttachmentPersistenceException, + TaskNotFoundException { + try { + Task task = taskService.createTask(testTask); + return taskService.getTask(task.getId()); + } finally { + testTask.setId(null); + testTask.setExternalId(null); + } + } + + public Task buildAndStore(TaskService taskService, String userId) + throws PrivilegedActionException { + Subject subject = new Subject(); + subject.getPrincipals().add(new UserPrincipal(userId)); + PrivilegedExceptionAction performBuildAndStore = () -> buildAndStore(taskService); + + return Subject.doAs(subject, performBuildAndStore); + } +} diff --git a/lib/taskana-core/src/main/java/pro/taskana/task/internal/builder/TaskTestImpl.java b/lib/taskana-core/src/main/java/pro/taskana/task/internal/builder/TaskTestImpl.java new file mode 100644 index 000000000..33fa780f2 --- /dev/null +++ b/lib/taskana-core/src/main/java/pro/taskana/task/internal/builder/TaskTestImpl.java @@ -0,0 +1,110 @@ +package pro.taskana.task.internal.builder; + +import java.time.Instant; + +import pro.taskana.task.api.TaskState; +import pro.taskana.task.internal.models.TaskImpl; + +class TaskTestImpl extends TaskImpl { + + private boolean freezeState = false; + private boolean freezeCreated = false; + private boolean freezeModified = false; + private boolean freezeRead = false; + private boolean freezeTransferred = false; + + @Override + public void setState(TaskState state) { + if (!freezeState) { + super.setState(state); + } + } + + public void setStateIgnoreFreeze(TaskState state) { + super.setState(state); + } + + @Override + public void setCreated(Instant created) { + if (!freezeCreated) { + super.setCreated(created); + } + } + + public void setCreatedIgnoreFreeze(Instant created) { + super.setCreated(created); + } + + @Override + public void setModified(Instant modified) { + if (!freezeModified) { + super.setModified(modified); + } + } + + public void setModifiedIgnoreFreeze(Instant modified) { + super.setModified(modified); + } + + @Override + public void setRead(boolean isRead) { + if (!freezeRead) { + super.setRead(isRead); + } + } + + public void setReadIgnoreFreeze(boolean isRead) { + super.setRead(isRead); + } + + @Override + public void setTransferred(boolean isTransferred) { + if (!freezeTransferred) { + super.setTransferred(isTransferred); + } + } + + public void setTransferredIgnoreFreeze(boolean isTransferred) { + super.setTransferred(isTransferred); + } + + public void freezeState() { + freezeState = true; + } + + public void unfreezeState() { + freezeState = false; + } + + public void freezeCreated() { + freezeCreated = true; + } + + public void unfreezeCreated() { + freezeCreated = false; + } + + public void freezeModified() { + freezeModified = true; + } + + public void unfreezeModified() { + freezeModified = false; + } + + public void freezeRead() { + freezeRead = true; + } + + public void unfreezeRead() { + freezeRead = false; + } + + public void freezeTransferred() { + freezeTransferred = true; + } + + public void unfreezeTransferred() { + freezeTransferred = false; + } +} diff --git a/lib/taskana-core/src/main/java/pro/taskana/workbasket/internal/WorkbasketAccessItemBuilder.java b/lib/taskana-core/src/main/java/pro/taskana/workbasket/internal/WorkbasketAccessItemBuilder.java new file mode 100644 index 000000000..78490b22f --- /dev/null +++ b/lib/taskana-core/src/main/java/pro/taskana/workbasket/internal/WorkbasketAccessItemBuilder.java @@ -0,0 +1,66 @@ +package pro.taskana.workbasket.internal; + +import java.security.PrivilegedActionException; +import java.security.PrivilegedExceptionAction; +import javax.security.auth.Subject; + +import pro.taskana.common.api.exceptions.InvalidArgumentException; +import pro.taskana.common.api.exceptions.NotAuthorizedException; +import pro.taskana.common.api.security.UserPrincipal; +import pro.taskana.workbasket.api.WorkbasketPermission; +import pro.taskana.workbasket.api.WorkbasketService; +import pro.taskana.workbasket.api.exceptions.WorkbasketAccessItemAlreadyExistException; +import pro.taskana.workbasket.api.exceptions.WorkbasketNotFoundException; +import pro.taskana.workbasket.api.models.WorkbasketAccessItem; +import pro.taskana.workbasket.internal.models.WorkbasketAccessItemImpl; + +public class WorkbasketAccessItemBuilder { + + WorkbasketAccessItemImpl testWorkbasketAccessItem = new WorkbasketAccessItemImpl(); + + private WorkbasketAccessItemBuilder() {} + + public static WorkbasketAccessItemBuilder newWorkbasketAccessItem() { + return new WorkbasketAccessItemBuilder(); + } + + public WorkbasketAccessItemBuilder workbasketId(String workbasketId) { + testWorkbasketAccessItem.setWorkbasketId(workbasketId); + return this; + } + + public WorkbasketAccessItemBuilder accessId(String accessId) { + testWorkbasketAccessItem.setAccessId(accessId); + return this; + } + + public WorkbasketAccessItemBuilder accessName(String accessName) { + testWorkbasketAccessItem.setAccessName(accessName); + return this; + } + + public WorkbasketAccessItemBuilder permission(WorkbasketPermission permission) { + return permission(permission, true); + } + + public WorkbasketAccessItemBuilder permission(WorkbasketPermission permission, boolean value) { + testWorkbasketAccessItem.setPermission(permission, value); + return this; + } + + public WorkbasketAccessItem buildAndStore(WorkbasketService workbasketService) + throws InvalidArgumentException, WorkbasketAccessItemAlreadyExistException, + WorkbasketNotFoundException, NotAuthorizedException { + return workbasketService.createWorkbasketAccessItem(testWorkbasketAccessItem); + } + + public WorkbasketAccessItem buildAndStore(WorkbasketService workbasketService, String userId) + throws PrivilegedActionException { + Subject subject = new Subject(); + subject.getPrincipals().add(new UserPrincipal(userId)); + PrivilegedExceptionAction performBuildAndStore = + () -> buildAndStore(workbasketService); + + return Subject.doAs(subject, performBuildAndStore); + } +} diff --git a/lib/taskana-core/src/main/java/pro/taskana/workbasket/internal/WorkbasketBuilder.java b/lib/taskana-core/src/main/java/pro/taskana/workbasket/internal/WorkbasketBuilder.java new file mode 100644 index 000000000..550f3d4eb --- /dev/null +++ b/lib/taskana-core/src/main/java/pro/taskana/workbasket/internal/WorkbasketBuilder.java @@ -0,0 +1,130 @@ +package pro.taskana.workbasket.internal; + +import java.security.PrivilegedActionException; +import java.security.PrivilegedExceptionAction; +import java.time.Instant; +import javax.security.auth.Subject; + +import pro.taskana.common.api.exceptions.DomainNotFoundException; +import pro.taskana.common.api.exceptions.InvalidArgumentException; +import pro.taskana.common.api.exceptions.NotAuthorizedException; +import pro.taskana.common.api.security.UserPrincipal; +import pro.taskana.workbasket.api.WorkbasketCustomField; +import pro.taskana.workbasket.api.WorkbasketService; +import pro.taskana.workbasket.api.WorkbasketType; +import pro.taskana.workbasket.api.exceptions.WorkbasketAlreadyExistException; +import pro.taskana.workbasket.api.exceptions.WorkbasketNotFoundException; +import pro.taskana.workbasket.api.models.Workbasket; + +public class WorkbasketBuilder { + + private final WorkbasketTestImpl testWorkbasket = new WorkbasketTestImpl(); + + private WorkbasketBuilder() {} + + public static WorkbasketBuilder newWorkbasket() { + return new WorkbasketBuilder(); + } + + public WorkbasketBuilder key(String key) { + testWorkbasket.setKey(key); + return this; + } + + public WorkbasketBuilder name(String name) { + testWorkbasket.setName(name); + return this; + } + + public WorkbasketBuilder description(String description) { + testWorkbasket.setDescription(description); + return this; + } + + public WorkbasketBuilder owner(String owner) { + testWorkbasket.setOwner(owner); + return this; + } + + public WorkbasketBuilder domain(String domain) { + testWorkbasket.setDomain(domain); + return this; + } + + public WorkbasketBuilder type(WorkbasketType type) { + testWorkbasket.setType(type); + return this; + } + + public WorkbasketBuilder customAttribute(WorkbasketCustomField customField, String value) { + testWorkbasket.setCustomAttribute(customField, value); + return this; + } + + public WorkbasketBuilder orgLevel1(String orgLevel1) { + testWorkbasket.setOrgLevel1(orgLevel1); + return this; + } + + public WorkbasketBuilder orgLevel2(String orgLevel2) { + testWorkbasket.setOrgLevel2(orgLevel2); + return this; + } + + public WorkbasketBuilder orgLevel3(String orgLevel3) { + testWorkbasket.setOrgLevel3(orgLevel3); + return this; + } + + public WorkbasketBuilder orgLevel4(String orgLevel4) { + testWorkbasket.setOrgLevel4(orgLevel4); + + return this; + } + + public WorkbasketBuilder markedForDeletion(boolean markedForDeletion) { + testWorkbasket.setMarkedForDeletion(markedForDeletion); + return this; + } + + public WorkbasketBuilder created(Instant created) { + testWorkbasket.setCreatedIgnoringFreeze(created); + if (created != null) { + testWorkbasket.freezeCreated(); + } else { + testWorkbasket.unfreezeCreated(); + } + return this; + } + + public WorkbasketBuilder modified(Instant modified) { + testWorkbasket.setModifiedIgnoringFreeze(modified); + if (modified != null) { + testWorkbasket.freezeModified(); + } else { + testWorkbasket.unfreezeModified(); + } + return this; + } + + public Workbasket buildAndStore(WorkbasketService workbasketService) + throws InvalidArgumentException, WorkbasketAlreadyExistException, DomainNotFoundException, + NotAuthorizedException, WorkbasketNotFoundException { + try { + Workbasket w = workbasketService.createWorkbasket(testWorkbasket); + return workbasketService.getWorkbasket(w.getId()); + } finally { + testWorkbasket.setId(null); + } + } + + public Workbasket buildAndStore(WorkbasketService workbasketService, String userId) + throws PrivilegedActionException { + Subject subject = new Subject(); + subject.getPrincipals().add(new UserPrincipal(userId)); + PrivilegedExceptionAction performBuildAndStore = + () -> buildAndStore(workbasketService); + + return Subject.doAs(subject, performBuildAndStore); + } +} diff --git a/lib/taskana-core/src/main/java/pro/taskana/workbasket/internal/WorkbasketServiceImpl.java b/lib/taskana-core/src/main/java/pro/taskana/workbasket/internal/WorkbasketServiceImpl.java index 13c54afe5..6f45324cd 100644 --- a/lib/taskana-core/src/main/java/pro/taskana/workbasket/internal/WorkbasketServiceImpl.java +++ b/lib/taskana-core/src/main/java/pro/taskana/workbasket/internal/WorkbasketServiceImpl.java @@ -262,6 +262,7 @@ public class WorkbasketServiceImpl implements WorkbasketService { if (wb == null) { throw new WorkbasketNotFoundException(workbasketAccessItem.getWorkbasketId()); } + accessItem.setWorkbasketKey(wb.getKey()); try { workbasketAccessMapper.insert(accessItem); diff --git a/lib/taskana-core/src/main/java/pro/taskana/workbasket/internal/WorkbasketTestImpl.java b/lib/taskana-core/src/main/java/pro/taskana/workbasket/internal/WorkbasketTestImpl.java new file mode 100644 index 000000000..d54a4fd91 --- /dev/null +++ b/lib/taskana-core/src/main/java/pro/taskana/workbasket/internal/WorkbasketTestImpl.java @@ -0,0 +1,49 @@ +package pro.taskana.workbasket.internal; + +import java.time.Instant; + +import pro.taskana.workbasket.internal.models.WorkbasketImpl; + +class WorkbasketTestImpl extends WorkbasketImpl { + + private boolean freezeCreated = false; + private boolean freezeModified = false; + + @Override + public void setCreated(Instant created) { + if (!freezeCreated) { + super.setCreated(created); + } + } + + public void setCreatedIgnoringFreeze(Instant created) { + super.setCreated(created); + } + + @Override + public void setModified(Instant modified) { + if (!freezeModified) { + super.setModified(modified); + } + } + + public void setModifiedIgnoringFreeze(Instant modified) { + super.setModified(modified); + } + + public void freezeCreated() { + freezeCreated = true; + } + + public void unfreezeCreated() { + freezeCreated = false; + } + + public void freezeModified() { + freezeModified = true; + } + + public void unfreezeModified() { + freezeModified = false; + } +} diff --git a/lib/taskana-core/src/test/java/acceptance/AbstractAccTest.java b/lib/taskana-core/src/test/java/acceptance/AbstractAccTest.java index 263d59e2e..a71bf5c30 100644 --- a/lib/taskana-core/src/test/java/acceptance/AbstractAccTest.java +++ b/lib/taskana-core/src/test/java/acceptance/AbstractAccTest.java @@ -22,6 +22,7 @@ import pro.taskana.common.api.TimeInterval; import pro.taskana.common.api.WorkingDaysToDaysConverter; import pro.taskana.common.internal.JobMapper; import pro.taskana.common.internal.TaskanaEngineImpl; +import pro.taskana.common.test.config.DataSourceGenerator; import pro.taskana.sampledata.SampleDataGenerator; import pro.taskana.task.api.models.Attachment; import pro.taskana.task.api.models.ObjectReference; @@ -46,8 +47,8 @@ public abstract class AbstractAccTest { protected static void resetDb(boolean dropTables) throws Exception { - DataSource dataSource = TaskanaEngineTestConfiguration.getDataSource(); - String schemaName = TaskanaEngineTestConfiguration.getSchemaName(); + DataSource dataSource = DataSourceGenerator.getDataSource(); + String schemaName = DataSourceGenerator.getSchemaName(); taskanaEngineConfiguration = new TaskanaEngineConfiguration(dataSource, false, schemaName); taskanaEngineConfiguration.setGermanPublicHolidaysEnabled(true); SampleDataGenerator sampleDataGenerator = diff --git a/lib/taskana-core/src/test/java/acceptance/DefaultTestEntities.java b/lib/taskana-core/src/test/java/acceptance/DefaultTestEntities.java new file mode 100644 index 000000000..6b752167a --- /dev/null +++ b/lib/taskana-core/src/test/java/acceptance/DefaultTestEntities.java @@ -0,0 +1,25 @@ +package acceptance; + +import pro.taskana.task.internal.ObjectReferenceBuilder; +import pro.taskana.workbasket.api.WorkbasketType; +import pro.taskana.workbasket.internal.WorkbasketBuilder; + +public class DefaultTestEntities { + + public static WorkbasketBuilder defaultTestWorkbasket() { + return WorkbasketBuilder.newWorkbasket() + .domain("DOMAIN_A") + .name("Megabasket") + .type(WorkbasketType.GROUP) + .orgLevel1("company"); + } + + public static ObjectReferenceBuilder defaultTestObjectReference() { + return ObjectReferenceBuilder.newObjectReference() + .company("Company1") + .system("System1") + .systemInstance("Instance1") + .type("Type1") + .value("Value1"); + } +} diff --git a/lib/taskana-core/src/test/java/acceptance/FooBar.java b/lib/taskana-core/src/test/java/acceptance/FooBar.java new file mode 100644 index 000000000..9099d4223 --- /dev/null +++ b/lib/taskana-core/src/test/java/acceptance/FooBar.java @@ -0,0 +1,21 @@ +package acceptance; + +import javax.sql.DataSource; + +import pro.taskana.TaskanaEngineConfiguration; +import pro.taskana.common.api.TaskanaEngine; +import pro.taskana.common.api.TaskanaEngine.ConnectionManagementMode; +import pro.taskana.common.test.config.DataSourceGenerator; + +public class FooBar { + public static TaskanaEngine getTaskanaEngineForTests() throws Exception { + DataSource dataSource = DataSourceGenerator.getDataSource(); + String schemaName = DataSourceGenerator.getSchemaName(); + TaskanaEngineConfiguration taskanaEngineConfiguration = + new TaskanaEngineConfiguration(dataSource, false, schemaName); + taskanaEngineConfiguration.setGermanPublicHolidaysEnabled(true); + TaskanaEngine taskanaEngine = taskanaEngineConfiguration.buildTaskanaEngine(); + taskanaEngine.setConnectionManagementMode(ConnectionManagementMode.AUTOCOMMIT); + return taskanaEngine; + } +} diff --git a/lib/taskana-core/src/test/java/acceptance/TaskanaEngineTestConfiguration.java b/lib/taskana-core/src/test/java/acceptance/TaskanaEngineTestConfiguration.java deleted file mode 100644 index c6fdf323d..000000000 --- a/lib/taskana-core/src/test/java/acceptance/TaskanaEngineTestConfiguration.java +++ /dev/null @@ -1,194 +0,0 @@ -package acceptance; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStream; -import java.util.Properties; -import javax.sql.DataSource; -import org.apache.ibatis.datasource.pooled.PooledDataSource; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** Integration Test for TaskanaEngineConfiguration. */ -public final class TaskanaEngineTestConfiguration { - - private static final Logger LOGGER = - LoggerFactory.getLogger(TaskanaEngineTestConfiguration.class); - private static final int POOL_TIME_TO_WAIT = 50; - private static final DataSource DATA_SOURCE; - private static String schemaName = null; - - static { - String userHomeDirectory = System.getProperty("user.home"); - String propertiesFileName = userHomeDirectory + "/taskanaUnitTest.properties"; - File f = new File(propertiesFileName); - if (f.exists() && !f.isDirectory()) { - DATA_SOURCE = createDataSourceFromProperties(propertiesFileName); - } else { - DATA_SOURCE = createDefaultDataSource(); - } - } - - private TaskanaEngineTestConfiguration() {} - - /** - * returns the Datasource used for Junit test. If the file {user.home}/taskanaUnitTest.properties - * is present, the Datasource is created according to the properties jdbcDriver, jdbcUrl, - * dbUserName and dbPassword. Assuming, the database has the name tskdb, a sample properties file - * for DB2 looks as follows: jdbcDriver=com.ibm.db2.jcc.DB2Driver - * jdbcUrl=jdbc:db2://localhost:50000/tskdb dbUserName=db2user dbPassword=db2password If any of - * these properties is missing, or the file doesn't exist, the default Datasource for h2 in-memory - * db is created. - * - * @return dataSource for unit test - */ - public static DataSource getDataSource() { - return DATA_SOURCE; - } - - /** - * returns the SchemaName used for Junit test. If the file {user.home}/taskanaUnitTest.properties - * is present, the SchemaName is created according to the property schemaName. a sample properties - * file for DB2 looks as follows: jdbcDriver=com.ibm.db2.jcc.DB2Driver - * jdbcUrl=jdbc:db2://localhost:50000/tskdb dbUserName=db2user dbPassword=db2password - * schemaName=TASKANA If any of these properties is missing, or the file doesn't exist, the - * default schemaName TASKANA is created used. - * - * @return String for unit test - */ - public static String getSchemaName() { - if (schemaName == null) { - String userHomeDirectory = System.getProperty("user.home"); - String propertiesFileName = userHomeDirectory + "/taskanaUnitTest.properties"; - File f = new File(propertiesFileName); - if (f.exists() && !f.isDirectory()) { - schemaName = getSchemaNameFromPropertiesObject(propertiesFileName); - } else { - schemaName = "TASKANA"; - } - } - return schemaName; - } - - /** - * create data source from properties file. - * - * @param propertiesFileName the name of the property file - * @return the parsed datasource. - */ - public static DataSource createDataSourceFromProperties(String propertiesFileName) { - DataSource ds; - try (InputStream input = new FileInputStream(propertiesFileName)) { - Properties prop = new Properties(); - prop.load(input); - boolean propertiesFileIsComplete = true; - String warningMessage = ""; - String jdbcDriver = prop.getProperty("jdbcDriver"); - if (jdbcDriver == null || jdbcDriver.length() == 0) { - propertiesFileIsComplete = false; - warningMessage += ", jdbcDriver property missing"; - } - String jdbcUrl = prop.getProperty("jdbcUrl"); - if (jdbcUrl == null || jdbcUrl.length() == 0) { - propertiesFileIsComplete = false; - warningMessage += ", jdbcUrl property missing"; - } - String dbUserName = prop.getProperty("dbUserName"); - if (dbUserName == null || dbUserName.length() == 0) { - propertiesFileIsComplete = false; - warningMessage += ", dbUserName property missing"; - } - String dbPassword = prop.getProperty("dbPassword"); - if (dbPassword == null || dbPassword.length() == 0) { - propertiesFileIsComplete = false; - warningMessage += ", dbPassword property missing"; - } - - if (propertiesFileIsComplete) { - ds = - new PooledDataSource( - Thread.currentThread().getContextClassLoader(), - jdbcDriver, - jdbcUrl, - dbUserName, - dbPassword); - ((PooledDataSource) ds) - .forceCloseAll(); // otherwise the MyBatis pool is not initialized correctly - } else { - LOGGER.warn("propertiesFile " + propertiesFileName + " is incomplete" + warningMessage); - LOGGER.warn("Using default Datasource for Test"); - ds = createDefaultDataSource(); - } - - } catch (IOException e) { - LOGGER.warn("createDataSourceFromProperties caught Exception " + e); - LOGGER.warn("Using default Datasource for Test"); - ds = createDefaultDataSource(); - } - - return ds; - } - - static String getSchemaNameFromPropertiesObject(String propertiesFileName) { - String schemaName = "TASKANA"; - try (InputStream input = new FileInputStream(propertiesFileName)) { - Properties prop = new Properties(); - prop.load(input); - boolean propertiesFileIsComplete = true; - String warningMessage = ""; - schemaName = prop.getProperty("schemaName"); - if (schemaName == null || schemaName.length() == 0) { - propertiesFileIsComplete = false; - warningMessage += ", schemaName property missing"; - } - - if (!propertiesFileIsComplete) { - LOGGER.warn("propertiesFile " + propertiesFileName + " is incomplete" + warningMessage); - LOGGER.warn("Using default Datasource for Test"); - schemaName = "TASKANA"; - } - - } catch (FileNotFoundException e) { - LOGGER.warn("getSchemaNameFromPropertiesObject caught Exception " + e); - LOGGER.warn("Using default schemaName for Test"); - } catch (IOException e) { - LOGGER.warn("createDataSourceFromProperties caught Exception " + e); - LOGGER.warn("Using default Datasource for Test"); - } - - return schemaName; - } - - /** - * create Default Datasource for in-memory database. - * - * @return the default datasource. - */ - private static DataSource createDefaultDataSource() { - // JdbcDataSource ds = new JdbcDataSource(); - // ds.setURL("jdbc:h2:mem:taskana;IGNORECASE=TRUE;LOCK_MODE=0"); - // ds.setPassword("sa"); - // ds.setUser("sa"); - - String jdbcDriver = "org.h2.Driver"; - String jdbcUrl = - "jdbc:h2:mem:taskana;" - // + "IGNORECASE=TRUE;" - + "LOCK_MODE=0;INIT=CREATE SCHEMA IF NOT EXISTS TASKANA\\;SET COLLATION DEFAULT_de_DE "; - String dbUserName = "sa"; - String dbPassword = "sa"; - PooledDataSource ds = - new PooledDataSource( - Thread.currentThread().getContextClassLoader(), - jdbcDriver, - jdbcUrl, - dbUserName, - dbPassword); - ds.setPoolTimeToWait(POOL_TIME_TO_WAIT); - ds.forceCloseAll(); // otherwise the MyBatis pool is not initialized correctly - - return ds; - } -} diff --git a/lib/taskana-core/src/test/java/acceptance/builder/ClassificationBuilderTest.java b/lib/taskana-core/src/test/java/acceptance/builder/ClassificationBuilderTest.java new file mode 100644 index 000000000..a463f0eb3 --- /dev/null +++ b/lib/taskana-core/src/test/java/acceptance/builder/ClassificationBuilderTest.java @@ -0,0 +1,213 @@ +package acceptance.builder; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatCode; +import static pro.taskana.classification.internal.ClassificationBuilder.newClassification; + +import acceptance.FooBar; +import java.time.Instant; +import java.util.List; +import java.util.function.BiFunction; +import java.util.function.Function; +import java.util.stream.Stream; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.DynamicContainer; +import org.junit.jupiter.api.DynamicTest; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestFactory; +import org.junit.jupiter.api.extension.ExtendWith; + +import pro.taskana.classification.api.ClassificationCustomField; +import pro.taskana.classification.api.ClassificationService; +import pro.taskana.classification.api.models.Classification; +import pro.taskana.classification.internal.ClassificationBuilder; +import pro.taskana.classification.internal.models.ClassificationImpl; +import pro.taskana.common.api.TaskanaEngine; +import pro.taskana.common.internal.util.Quadruple; +import pro.taskana.common.test.security.JaasExtension; +import pro.taskana.common.test.security.WithAccessId; + +@ExtendWith(JaasExtension.class) +class ClassificationBuilderTest { + + private static ClassificationService classificationService; + + @BeforeAll + static void setup() throws Exception { + TaskanaEngine taskanaEngine = FooBar.getTaskanaEngineForTests(); + classificationService = taskanaEngine.getClassificationService(); + } + + @WithAccessId(user = "businessadmin") + @Test + void should_PersistClassification_When_UsingClassificationBuilder() throws Exception { + Classification classification = + newClassification().key("key0_A").domain("DOMAIN_A").buildAndStore(classificationService); + + Classification receivedClassification = + classificationService.getClassification(classification.getId()); + assertThat(receivedClassification).isEqualTo(classification); + } + + @Test + void should_PersistClassificationAsUser_When_UsingClassificationBuilder() throws Exception { + Classification classification = + newClassification() + .key("key1_A") + .domain("DOMAIN_A") + .buildAndStore(classificationService, "businessadmin"); + + Classification receivedClassification = + classificationService.getClassification(classification.getId()); + assertThat(receivedClassification).isEqualTo(classification); + } + + @WithAccessId(user = "businessadmin") + @Test + void should_PopulateClassification_When_UsingEveryBuilderFunction() throws Exception { + Classification parentClassification = + newClassification() + .key("parent classification") + .domain("DOMAIN_A") + .buildAndStore(classificationService); + final Classification classification = + newClassification() + .applicationEntryPoint("application entry point") + .category("MANUAL") + .domain("DOMAIN_A") + .key("key2_A") + .name("dope Classification name") + .parentId(parentClassification.getId()) + .parentKey(parentClassification.getKey()) + .priority(1337) + .serviceLevel("P15D") + .type("TASK") + .customAttribute(ClassificationCustomField.CUSTOM_1, "custom 1 value") + .customAttribute(ClassificationCustomField.CUSTOM_2, "custom 2 value") + .customAttribute(ClassificationCustomField.CUSTOM_3, "custom 3 value") + .customAttribute(ClassificationCustomField.CUSTOM_4, "custom 4 value") + .customAttribute(ClassificationCustomField.CUSTOM_5, "custom 5 value") + .customAttribute(ClassificationCustomField.CUSTOM_6, "custom 6 value") + .customAttribute(ClassificationCustomField.CUSTOM_7, "custom 7 value") + .customAttribute(ClassificationCustomField.CUSTOM_8, "custom 8 value") + .isValidInDomain(false) + .created(Instant.parse("2021-05-17T07:16:26.747Z")) + .modified(Instant.parse("2021-05-18T07:16:26.747Z")) + .description("this is a dope description") + .buildAndStore(classificationService); + + ClassificationImpl expectedClassification = + (ClassificationImpl) classificationService.newClassification("key2_A", "DOMAIN_A", "TASK"); + expectedClassification.setApplicationEntryPoint("application entry point"); + expectedClassification.setCategory("MANUAL"); + expectedClassification.setName("dope Classification name"); + expectedClassification.setParentId(parentClassification.getId()); + expectedClassification.setParentKey(parentClassification.getKey()); + expectedClassification.setPriority(1337); + expectedClassification.setServiceLevel("P15D"); + expectedClassification.setCustomAttribute(ClassificationCustomField.CUSTOM_1, "custom 1 value"); + expectedClassification.setCustomAttribute(ClassificationCustomField.CUSTOM_2, "custom 2 value"); + expectedClassification.setCustomAttribute(ClassificationCustomField.CUSTOM_3, "custom 3 value"); + expectedClassification.setCustomAttribute(ClassificationCustomField.CUSTOM_4, "custom 4 value"); + expectedClassification.setCustomAttribute(ClassificationCustomField.CUSTOM_5, "custom 5 value"); + expectedClassification.setCustomAttribute(ClassificationCustomField.CUSTOM_6, "custom 6 value"); + expectedClassification.setCustomAttribute(ClassificationCustomField.CUSTOM_7, "custom 7 value"); + expectedClassification.setCustomAttribute(ClassificationCustomField.CUSTOM_8, "custom 8 value"); + expectedClassification.setIsValidInDomain(false); + expectedClassification.setCreated(Instant.parse("2021-05-17T07:16:26.747Z")); + expectedClassification.setModified(Instant.parse("2021-05-18T07:16:26.747Z")); + expectedClassification.setDescription("this is a dope description"); + + assertThat(classification) + .hasNoNullFieldsOrProperties() + .usingRecursiveComparison() + .ignoringFields("id") + .isEqualTo(expectedClassification); + } + + @WithAccessId(user = "businessadmin") + @Test + void should_ResetClassificationId_When_StoringClassificationMultipleTimes() { + ClassificationBuilder builder = newClassification().domain("DOMAIN_A"); + + assertThatCode( + () -> { + builder.key("key4_A").buildAndStore(classificationService); + builder.key("key5_A").buildAndStore(classificationService); + }) + .doesNotThrowAnyException(); + } + + @WithAccessId(user = "businessadmin") + @TestFactory + Stream should_PersistClassification_When_CreatingEntityWithInvalidApiValues() { + List< + Quadruple< + String, + Object, + BiFunction, + Function>> + list = + List.of( + Quadruple.of( + "created", + Instant.parse("2020-05-17T07:16:26.747Z"), + (b, v) -> b.created((Instant) v), + Classification::getCreated), + Quadruple.of( + "modified", + Instant.parse("2019-05-17T07:16:26.747Z"), + (b, v) -> b.modified((Instant) v), + Classification::getModified)); + + Stream applyBuilderFunction = + DynamicTest.stream( + list.iterator(), + q -> String.format("for field: '%s'", q.getFirst()), + q -> applyBuilderFunctionAndVerifyValue(q.getSecond(), q.getThird(), q.getFourth())); + + Stream overrideBuilderFunctionWithApiDefault = + DynamicTest.stream( + list.iterator(), + q -> String.format("for field: '%s'", q.getFirst()), + t -> applyAndOverrideWithApiDefaultValue(t.getSecond(), t.getThird(), t.getFourth())); + + return Stream.of( + DynamicContainer.dynamicContainer( + "set values which are invalid through API", applyBuilderFunction), + DynamicContainer.dynamicContainer( + "override with API default value", overrideBuilderFunctionWithApiDefault)); + } + + private void applyBuilderFunctionAndVerifyValue( + T value, + BiFunction builderfunction, + Function retriever) + throws Exception { + ClassificationBuilder builder = + newClassification().domain("DOMAIN_A").key("A" + builderfunction.hashCode()); + + builderfunction.apply(builder, value); + Classification classification = builder.buildAndStore(classificationService); + T retrievedValue = retriever.apply(classification); + + assertThat(retrievedValue).isEqualTo(value); + } + + private void applyAndOverrideWithApiDefaultValue( + T value, + BiFunction builderfunction, + Function retriever) + throws Exception { + ClassificationBuilder builder = + newClassification().domain("DOMAIN_A").key("B" + builderfunction.hashCode()); + + builderfunction.apply(builder, value); + builderfunction.apply(builder, null); + + Classification classification = builder.buildAndStore(classificationService); + T retrievedValue = retriever.apply(classification); + + assertThat(retrievedValue).isNotNull().isNotEqualTo(value); + } +} diff --git a/lib/taskana-core/src/test/java/acceptance/builder/ObjectReferenceBuilderTest.java b/lib/taskana-core/src/test/java/acceptance/builder/ObjectReferenceBuilderTest.java new file mode 100644 index 000000000..8ef8f836d --- /dev/null +++ b/lib/taskana-core/src/test/java/acceptance/builder/ObjectReferenceBuilderTest.java @@ -0,0 +1,34 @@ +package acceptance.builder; + +import static org.assertj.core.api.Assertions.assertThat; +import static pro.taskana.task.internal.ObjectReferenceBuilder.newObjectReference; + +import org.junit.jupiter.api.Test; + +import pro.taskana.task.api.models.ObjectReference; + +class ObjectReferenceBuilderTest { + + @Test + void should_PopulateObjectReference_When_UsingEveryBuilderFunction() { + final ObjectReference objectReference = + newObjectReference() + .company("Company1") + .system("System1") + .systemInstance("Instance1") + .type("Type1") + .value("Value1") + .build(); + + ObjectReference expectedObjectReference = new ObjectReference(); + expectedObjectReference.setCompany("Company1"); + expectedObjectReference.setSystem("System1"); + expectedObjectReference.setSystemInstance("Instance1"); + expectedObjectReference.setType("Type1"); + expectedObjectReference.setValue("Value1"); + + assertThat(objectReference) + .hasNoNullFieldsOrPropertiesExcept("id") + .isEqualTo(expectedObjectReference); + } +} diff --git a/lib/taskana-core/src/test/java/acceptance/builder/TaskAttachmentBuilderTest.java b/lib/taskana-core/src/test/java/acceptance/builder/TaskAttachmentBuilderTest.java new file mode 100644 index 000000000..5738039fb --- /dev/null +++ b/lib/taskana-core/src/test/java/acceptance/builder/TaskAttachmentBuilderTest.java @@ -0,0 +1,73 @@ +package acceptance.builder; + +import static org.assertj.core.api.AssertionsForClassTypes.assertThat; + +import acceptance.DefaultTestEntities; +import acceptance.FooBar; +import java.time.Instant; +import java.util.Map; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; + +import pro.taskana.classification.api.ClassificationService; +import pro.taskana.classification.api.models.ClassificationSummary; +import pro.taskana.classification.internal.ClassificationBuilder; +import pro.taskana.common.api.TaskanaEngine; +import pro.taskana.common.test.security.JaasExtension; +import pro.taskana.task.api.TaskService; +import pro.taskana.task.api.models.Attachment; +import pro.taskana.task.api.models.ObjectReference; +import pro.taskana.task.internal.TaskAttachmentBuilder; +import pro.taskana.task.internal.models.AttachmentImpl; + +@ExtendWith(JaasExtension.class) +class TaskAttachmentBuilderTest { + + private static ClassificationService classificationService; + private static TaskService taskService; + + @BeforeAll + static void setup() throws Exception { + TaskanaEngine taskanaEngine = FooBar.getTaskanaEngineForTests(); + classificationService = taskanaEngine.getClassificationService(); + taskService = taskanaEngine.getTaskService(); + } + + @Test + void should_PopulateAttachment_When_UsingEveryBuilderFunction() throws Exception { + ClassificationSummary classificationSummary = + ClassificationBuilder.newClassification() + .domain("DOMAIN_A") + .key("key") + .buildAndStore(classificationService, "businessadmin") + .asSummary(); + ObjectReference objectReference = DefaultTestEntities.defaultTestObjectReference().build(); + + final Attachment attachment = + TaskAttachmentBuilder.newAttachment() + .received(Instant.parse("2010-01-01T12:00:00Z")) + .created(Instant.parse("2010-01-02T12:00:00Z")) + .modified(Instant.parse("2010-01-03T12:00:00Z")) + .classificationSummary(classificationSummary) + .objectReference(objectReference) + .channel("Channel Super Fun") + .customAttributes(Map.of("custom", "attribute")) + .build(); + + AttachmentImpl expectedAttachment = (AttachmentImpl) taskService.newAttachment(); + expectedAttachment.setReceived(Instant.parse("2010-01-01T12:00:00Z")); + expectedAttachment.setCreated(Instant.parse("2010-01-02T12:00:00Z")); + expectedAttachment.setModified(Instant.parse("2010-01-03T12:00:00Z")); + expectedAttachment.setClassificationSummary(classificationSummary); + expectedAttachment.setObjectReference(objectReference); + expectedAttachment.setChannel("Channel Super Fun"); + expectedAttachment.setCustomAttributes(Map.of("custom", "attribute")); + + assertThat(attachment) + .hasNoNullFieldsOrPropertiesExcept("id", "taskId") + .usingRecursiveComparison() + .ignoringFields("id") + .isEqualTo(expectedAttachment); + } +} diff --git a/lib/taskana-core/src/test/java/acceptance/builder/TaskBuilderTest.java b/lib/taskana-core/src/test/java/acceptance/builder/TaskBuilderTest.java new file mode 100644 index 000000000..c6d7dd15d --- /dev/null +++ b/lib/taskana-core/src/test/java/acceptance/builder/TaskBuilderTest.java @@ -0,0 +1,310 @@ +package acceptance.builder; + +import static acceptance.DefaultTestEntities.defaultTestObjectReference; +import static acceptance.DefaultTestEntities.defaultTestWorkbasket; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatCode; +import static pro.taskana.classification.internal.ClassificationBuilder.newClassification; +import static pro.taskana.common.internal.util.CheckedSupplier.wrap; +import static pro.taskana.task.internal.builder.TaskBuilder.newTask; +import static pro.taskana.workbasket.internal.WorkbasketAccessItemBuilder.newWorkbasketAccessItem; + +import acceptance.FooBar; +import java.time.Instant; +import java.util.List; +import java.util.Map; +import java.util.function.BiFunction; +import java.util.function.Function; +import java.util.stream.Stream; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.DynamicContainer; +import org.junit.jupiter.api.DynamicTest; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestFactory; +import org.junit.jupiter.api.extension.ExtendWith; + +import pro.taskana.classification.api.ClassificationService; +import pro.taskana.classification.api.models.ClassificationSummary; +import pro.taskana.common.api.TaskanaEngine; +import pro.taskana.common.internal.util.Quadruple; +import pro.taskana.common.test.security.JaasExtension; +import pro.taskana.common.test.security.WithAccessId; +import pro.taskana.task.api.CallbackState; +import pro.taskana.task.api.TaskCustomField; +import pro.taskana.task.api.TaskService; +import pro.taskana.task.api.TaskState; +import pro.taskana.task.api.models.Attachment; +import pro.taskana.task.api.models.Task; +import pro.taskana.task.internal.TaskAttachmentBuilder; +import pro.taskana.task.internal.builder.TaskBuilder; +import pro.taskana.task.internal.models.TaskImpl; +import pro.taskana.workbasket.api.WorkbasketPermission; +import pro.taskana.workbasket.api.WorkbasketService; +import pro.taskana.workbasket.api.models.WorkbasketSummary; + +@ExtendWith(JaasExtension.class) +class TaskBuilderTest { + private static TaskService taskService; + private static WorkbasketSummary workbasketSummary; + private static ClassificationSummary classificationSummary; + private static TaskanaEngine taskanaEngine; + + @WithAccessId(user = "businessadmin") + @BeforeAll + static void setup() throws Exception { + taskanaEngine = FooBar.getTaskanaEngineForTests(); + taskService = taskanaEngine.getTaskService(); + WorkbasketService workbasketService = taskanaEngine.getWorkbasketService(); + ClassificationService classificationService = taskanaEngine.getClassificationService(); + + workbasketSummary = + defaultTestWorkbasket() + .owner("user-1-1") + .key("key0_D") + .buildAndStore(workbasketService) + .asSummary(); + classificationSummary = + newClassification() + .key("key0_D") + .domain("DOMAIN_A") + .buildAndStore(classificationService) + .asSummary(); + newWorkbasketAccessItem() + .workbasketId(workbasketSummary.getId()) + .accessId("user-1-1") + .permission(WorkbasketPermission.APPEND) + .permission(WorkbasketPermission.READ) + .buildAndStore(workbasketService); + } + + @WithAccessId(user = "user-1-1") + @Test + void should_PersistTask_When_UsingTaskBuilder() throws Exception { + Task task = + newTask() + .workbasketSummary(workbasketSummary) + .classificationSummary(classificationSummary) + .primaryObjRef(defaultTestObjectReference().build()) + .buildAndStore(taskService); + + Task receivedTask = taskService.getTask(task.getId()); + assertThat(receivedTask).isEqualTo(task); + } + + @Test + void should_PersistTaskAsUser_When_UsingTaskBuilder() throws Exception { + Task task = + newTask() + .workbasketSummary(workbasketSummary) + .classificationSummary(classificationSummary) + .primaryObjRef(defaultTestObjectReference().build()) + .buildAndStore(taskService, "user-1-1"); + + Task receivedTask = taskanaEngine.runAsAdmin(wrap(() -> taskService.getTask(task.getId()))); + assertThat(receivedTask).isEqualTo(task); + assertThat(receivedTask.getCreator()).isEqualTo("user-1-1"); + } + + @WithAccessId(user = "user-1-1") + @Test + void should_PopulateTask_When_UsingEveryBuilderFunction() throws Exception { + Attachment attachment = + TaskAttachmentBuilder.newAttachment() + .classificationSummary(classificationSummary) + .objectReference(defaultTestObjectReference().build()) + .build(); + + final Task task = + newTask() + .externalId("external id") + .received(Instant.parse("2020-04-19T13:13:00.000Z")) + .created(Instant.parse("2020-04-20T13:13:00.000Z")) + .claimed(Instant.parse("2020-04-21T13:13:00.000Z")) + .completed(Instant.parse("2020-04-22T13:13:00.000Z")) + .modified(Instant.parse("2020-04-22T13:13:00.000Z")) + .planned(Instant.parse("2020-04-21T13:13:00.000Z")) + .due(Instant.parse("2020-04-21T13:13:00.000Z")) + .name("Voll der geile Task") + .note("Jap, voll geil") + .description("Mega!") + .state(TaskState.COMPLETED) + .classificationSummary(classificationSummary) + .workbasketSummary(workbasketSummary) + .businessProcessId("BPI:Cool") + .parentBusinessProcessId("BPI:ParentIsCool") + .owner("hanspeter") + .primaryObjRef(defaultTestObjectReference().build()) + .read(true) + .transferred(true) + .attachments(attachment) + .customAttribute(TaskCustomField.CUSTOM_1, "custom1") + .customAttribute(TaskCustomField.CUSTOM_2, "custom2") + .customAttribute(TaskCustomField.CUSTOM_3, "custom3") + .customAttribute(TaskCustomField.CUSTOM_4, "custom4") + .customAttribute(TaskCustomField.CUSTOM_5, "custom5") + .customAttribute(TaskCustomField.CUSTOM_6, "custom6") + .customAttribute(TaskCustomField.CUSTOM_7, "custom7") + .customAttribute(TaskCustomField.CUSTOM_8, "custom8") + .customAttribute(TaskCustomField.CUSTOM_9, "custom9") + .customAttribute(TaskCustomField.CUSTOM_10, "custom10") + .customAttribute(TaskCustomField.CUSTOM_11, "custom11") + .customAttribute(TaskCustomField.CUSTOM_12, "custom12") + .customAttribute(TaskCustomField.CUSTOM_13, "custom13") + .customAttribute(TaskCustomField.CUSTOM_14, "custom14") + .customAttribute(TaskCustomField.CUSTOM_15, "custom15") + .customAttribute(TaskCustomField.CUSTOM_16, "custom16") + .callbackInfo(Map.of("custom", "value")) + .callbackState(CallbackState.CALLBACK_PROCESSING_COMPLETED) + .buildAndStore(taskService); + + TaskImpl expectedTask = (TaskImpl) taskService.newTask(workbasketSummary.getId()); + expectedTask.setExternalId("external id"); + expectedTask.setReceived(Instant.parse("2020-04-19T13:13:00.000Z")); + expectedTask.setCreated(Instant.parse("2020-04-20T13:13:00.000Z")); + expectedTask.setClaimed(Instant.parse("2020-04-21T13:13:00.000Z")); + expectedTask.setCompleted(Instant.parse("2020-04-22T13:13:00.000Z")); + expectedTask.setModified(Instant.parse("2020-04-22T13:13:00.000Z")); + expectedTask.setPlanned(Instant.parse("2020-04-21T13:13:00.000Z")); + expectedTask.setDue(Instant.parse("2020-04-21T13:13:00.000Z")); + expectedTask.setName("Voll der geile Task"); + expectedTask.setNote("Jap, voll geil"); + expectedTask.setDescription("Mega!"); + expectedTask.setState(TaskState.COMPLETED); + expectedTask.setClassificationSummary(classificationSummary); + expectedTask.setWorkbasketSummary(workbasketSummary); + expectedTask.setBusinessProcessId("BPI:Cool"); + expectedTask.setParentBusinessProcessId("BPI:ParentIsCool"); + expectedTask.setOwner("hanspeter"); + expectedTask.setPrimaryObjRef(defaultTestObjectReference().build()); + expectedTask.setRead(true); + expectedTask.setTransferred(true); + expectedTask.setCreator("user-1-1"); + expectedTask.addAttachment(attachment); + // ATTENTION: We have an SPI running which transforms custom1 of every created Task to that. + // Please fix after removal of that SPI during TSK-1704 ;) + expectedTask.setCustomAttribute(TaskCustomField.CUSTOM_1, "preprocessedCustomField"); + expectedTask.setCustomAttribute(TaskCustomField.CUSTOM_2, "custom2"); + expectedTask.setCustomAttribute(TaskCustomField.CUSTOM_3, "custom3"); + expectedTask.setCustomAttribute(TaskCustomField.CUSTOM_4, "custom4"); + expectedTask.setCustomAttribute(TaskCustomField.CUSTOM_5, "custom5"); + expectedTask.setCustomAttribute(TaskCustomField.CUSTOM_6, "custom6"); + expectedTask.setCustomAttribute(TaskCustomField.CUSTOM_7, "custom7"); + expectedTask.setCustomAttribute(TaskCustomField.CUSTOM_8, "custom8"); + expectedTask.setCustomAttribute(TaskCustomField.CUSTOM_9, "custom9"); + expectedTask.setCustomAttribute(TaskCustomField.CUSTOM_10, "custom10"); + expectedTask.setCustomAttribute(TaskCustomField.CUSTOM_11, "custom11"); + expectedTask.setCustomAttribute(TaskCustomField.CUSTOM_12, "custom12"); + expectedTask.setCustomAttribute(TaskCustomField.CUSTOM_13, "custom13"); + expectedTask.setCustomAttribute(TaskCustomField.CUSTOM_14, "custom14"); + expectedTask.setCustomAttribute(TaskCustomField.CUSTOM_15, "custom15"); + expectedTask.setCustomAttribute(TaskCustomField.CUSTOM_16, "custom16"); + expectedTask.setCallbackInfo(Map.of("custom", "value")); + expectedTask.setCallbackState(CallbackState.CALLBACK_PROCESSING_COMPLETED); + + assertThat(task) + .hasNoNullFieldsOrProperties() + .usingRecursiveComparison() + .ignoringFields("id") + .isEqualTo(expectedTask); + } + + @WithAccessId(user = "user-1-1") + @Test + void should_ResetTaskId_When_StoringTaskMultipleTimes() { + TaskBuilder builder = + newTask() + .workbasketSummary(workbasketSummary) + .classificationSummary(classificationSummary) + .primaryObjRef(defaultTestObjectReference().build()); + + assertThatCode( + () -> { + builder.buildAndStore(taskService); + builder.buildAndStore(taskService); + }) + .doesNotThrowAnyException(); + } + + @WithAccessId(user = "user-1-1") + @TestFactory + Stream should_PersistClassification_When_CreatingEntityWithInvalidApiValues() { + List< + Quadruple< + String, + Object, + BiFunction, + Function>> + list = + List.of( + Quadruple.of( + "state", TaskState.CANCELLED, (b, v) -> b.state((TaskState) v), Task::getState), + Quadruple.of( + "created", + Instant.parse("2020-05-17T07:16:26.747Z"), + (b, v) -> b.created((Instant) v), + Task::getCreated), + Quadruple.of( + "modified", + Instant.parse("2019-05-17T07:16:26.747Z"), + (b, v) -> b.modified((Instant) v), + Task::getModified), + Quadruple.of("read", true, (b, v) -> b.read((Boolean) v), Task::isRead), + Quadruple.of( + "transferred", + true, + (b, v) -> b.transferred((Boolean) v), + Task::isTransferred)); + + Stream applyBuilderFunction = + DynamicTest.stream( + list.iterator(), + q -> String.format("for field: '%s'", q.getFirst()), + q -> applyBuilderFunctionAndVerifyValue(q.getSecond(), q.getThird(), q.getFourth())); + + Stream overrideBuilderFunctionWithApiDefault = + DynamicTest.stream( + list.iterator(), + q -> String.format("for field: '%s'", q.getFirst()), + t -> applyAndOverrideWithApiDefaultValue(t.getSecond(), t.getThird(), t.getFourth())); + + return Stream.of( + DynamicContainer.dynamicContainer( + "set values which are invalid through API", applyBuilderFunction), + DynamicContainer.dynamicContainer( + "override with API default value", overrideBuilderFunctionWithApiDefault)); + } + + private void applyBuilderFunctionAndVerifyValue( + T value, BiFunction builderfunction, Function retriever) + throws Exception { + TaskBuilder builder = + newTask() + .workbasketSummary(workbasketSummary) + .classificationSummary(classificationSummary) + .primaryObjRef(defaultTestObjectReference().build()); + + builderfunction.apply(builder, value); + Task task = builder.buildAndStore(taskService); + T retrievedValue = retriever.apply(task); + + assertThat(retrievedValue).isEqualTo(value); + } + + private void applyAndOverrideWithApiDefaultValue( + T value, BiFunction builderfunction, Function retriever) + throws Exception { + TaskBuilder builder = + newTask() + .workbasketSummary(workbasketSummary) + .classificationSummary(classificationSummary) + .primaryObjRef(defaultTestObjectReference().build()); + + builderfunction.apply(builder, value); + builderfunction.apply(builder, null); + + Task task = builder.buildAndStore(taskService); + T retrievedValue = retriever.apply(task); + + assertThat(retrievedValue).isNotNull().isNotEqualTo(value); + } +} diff --git a/lib/taskana-core/src/test/java/acceptance/builder/TaskCommentBuilderTest.java b/lib/taskana-core/src/test/java/acceptance/builder/TaskCommentBuilderTest.java new file mode 100644 index 000000000..0d76e4c5b --- /dev/null +++ b/lib/taskana-core/src/test/java/acceptance/builder/TaskCommentBuilderTest.java @@ -0,0 +1,202 @@ +package acceptance.builder; + +import static acceptance.DefaultTestEntities.defaultTestObjectReference; +import static acceptance.DefaultTestEntities.defaultTestWorkbasket; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatCode; +import static pro.taskana.classification.internal.ClassificationBuilder.newClassification; +import static pro.taskana.common.internal.util.CheckedSupplier.wrap; +import static pro.taskana.task.internal.TaskCommentBuilder.newTaskComment; +import static pro.taskana.workbasket.internal.WorkbasketAccessItemBuilder.newWorkbasketAccessItem; + +import acceptance.FooBar; +import java.time.Instant; +import java.util.List; +import java.util.function.BiFunction; +import java.util.function.Function; +import java.util.stream.Stream; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.DynamicContainer; +import org.junit.jupiter.api.DynamicTest; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestFactory; +import org.junit.jupiter.api.extension.ExtendWith; + +import pro.taskana.classification.api.ClassificationService; +import pro.taskana.classification.api.models.Classification; +import pro.taskana.common.api.TaskanaEngine; +import pro.taskana.common.internal.util.Quadruple; +import pro.taskana.common.test.security.JaasExtension; +import pro.taskana.common.test.security.WithAccessId; +import pro.taskana.task.api.TaskService; +import pro.taskana.task.api.models.ObjectReference; +import pro.taskana.task.api.models.Task; +import pro.taskana.task.api.models.TaskComment; +import pro.taskana.task.internal.TaskCommentBuilder; +import pro.taskana.task.internal.builder.TaskBuilder; +import pro.taskana.task.internal.models.TaskCommentImpl; +import pro.taskana.workbasket.api.WorkbasketPermission; +import pro.taskana.workbasket.api.WorkbasketService; +import pro.taskana.workbasket.api.models.Workbasket; + +@ExtendWith(JaasExtension.class) +class TaskCommentBuilderTest { + + private static TaskService taskService; + private static Task task; + private static TaskanaEngine taskanaEngine; + + @WithAccessId(user = "businessadmin") + @BeforeAll + static void setup() throws Exception { + taskanaEngine = FooBar.getTaskanaEngineForTests(); + taskService = taskanaEngine.getTaskService(); + WorkbasketService workbasketService = taskanaEngine.getWorkbasketService(); + ClassificationService classificationService = taskanaEngine.getClassificationService(); + + ObjectReference objectReference = defaultTestObjectReference().build(); + Workbasket workbasket = + defaultTestWorkbasket().owner("user-1-1").key("key0_E").buildAndStore(workbasketService); + Classification classification = + newClassification().key("key0_E").domain("DOMAIN_A").buildAndStore(classificationService); + newWorkbasketAccessItem() + .workbasketId(workbasket.getId()) + .permission(WorkbasketPermission.READ) + .accessId("user-1-1") + .buildAndStore(workbasketService); + task = + TaskBuilder.newTask() + .workbasketSummary(workbasket) + .classificationSummary(classification) + .primaryObjRef(objectReference) + .buildAndStore(taskService, "admin"); + } + + @WithAccessId(user = "user-1-1") + @Test + void should_PersistTaskComment_When_UsingTaskCommentBuilder() throws Exception { + TaskComment taskComment = newTaskComment().taskId(task.getId()).buildAndStore(taskService); + + TaskComment receivedTaskComment = taskService.getTaskComment(taskComment.getId()); + assertThat(receivedTaskComment).isEqualTo(taskComment); + } + + @Test + void should_PersistTaskCommentAsUser_When_UsingTaskCommentBuilder() throws Exception { + TaskComment taskComment = + newTaskComment().taskId(task.getId()).buildAndStore(taskService, "user-1-1"); + + TaskComment receivedTaskComment = + taskanaEngine.runAsAdmin(wrap(() -> taskService.getTaskComment(taskComment.getId()))); + assertThat(receivedTaskComment).isEqualTo(taskComment); + assertThat(receivedTaskComment.getCreator()).isEqualTo("user-1-1"); + } + + @WithAccessId(user = "user-1-1") + @Test + void should_PopulateTaskComment_When_UsingEveryBuilderFunction() throws Exception { + final TaskComment taskComment = + newTaskComment() + .taskId(task.getId()) + .textField("A comment from the TEST-API. :)") + .created(Instant.parse("2020-04-30T07:12:00.000Z")) + .modified(Instant.parse("2020-04-30T07:12:00.000Z")) + .buildAndStore(taskService); + + TaskCommentImpl expectedTaskComment = + (TaskCommentImpl) taskService.newTaskComment(task.getId()); + expectedTaskComment.setTextField("A comment from the TEST-API. :)"); + expectedTaskComment.setCreated(Instant.parse("2020-04-30T07:12:00.000Z")); + expectedTaskComment.setModified(Instant.parse("2020-04-30T07:12:00.000Z")); + expectedTaskComment.setCreator("user-1-1"); + + assertThat(taskComment) + .hasNoNullFieldsOrPropertiesExcept() + .usingRecursiveComparison() + .ignoringFields("id") + .isEqualTo(expectedTaskComment); + } + + @WithAccessId(user = "user-1-1") + @Test + void should_ResetTaskCommentId_When_StoringTaskCommentMultipleTimes() { + TaskCommentBuilder builder = newTaskComment().taskId(task.getId()); + + assertThatCode( + () -> { + builder.buildAndStore(taskService); + builder.buildAndStore(taskService); + }) + .doesNotThrowAnyException(); + } + + @WithAccessId(user = "user-1-1") + @TestFactory + Stream should_PersistTaskComment_When_CreatingEntityWithInvalidApiValues() { + List< + Quadruple< + String, + Object, + BiFunction, + Function>> + list = + List.of( + Quadruple.of( + "created", + Instant.parse("2020-05-17T07:16:26.747Z"), + (b, v) -> b.created((Instant) v), + TaskComment::getCreated), + Quadruple.of( + "modified", + Instant.parse("2019-05-17T07:16:26.747Z"), + (b, v) -> b.modified((Instant) v), + TaskComment::getModified)); + + Stream applyBuilderFunction = + DynamicTest.stream( + list.iterator(), + q -> String.format("for field: '%s'", q.getFirst()), + q -> applyBuilderFunctionAndVerifyValue(q.getSecond(), q.getThird(), q.getFourth())); + + Stream overrideBuilderFunctionWithApiDefault = + DynamicTest.stream( + list.iterator(), + q -> String.format("for field: '%s'", q.getFirst()), + t -> applyAndOverrideWithApiDefaultValue(t.getSecond(), t.getThird(), t.getFourth())); + + return Stream.of( + DynamicContainer.dynamicContainer( + "set values which are invalid through API", applyBuilderFunction), + DynamicContainer.dynamicContainer( + "override with API default value", overrideBuilderFunctionWithApiDefault)); + } + + private void applyBuilderFunctionAndVerifyValue( + T value, + BiFunction builderfunction, + Function retriever) + throws Exception { + TaskCommentBuilder builder = newTaskComment().taskId(task.getId()); + builderfunction.apply(builder, value); + TaskComment classification = builder.buildAndStore(taskService); + T retrievedValue = retriever.apply(classification); + + assertThat(retrievedValue).isEqualTo(value); + } + + private void applyAndOverrideWithApiDefaultValue( + T value, + BiFunction builderfunction, + Function retriever) + throws Exception { + TaskCommentBuilder builder = newTaskComment().taskId(task.getId()); + + builderfunction.apply(builder, value); + builderfunction.apply(builder, null); + + TaskComment classification = builder.buildAndStore(taskService); + T retrievedValue = retriever.apply(classification); + + assertThat(retrievedValue).isNotNull().isNotEqualTo(value); + } +} diff --git a/lib/taskana-core/src/test/java/acceptance/builder/WorkbasketAccessItemBuilderTest.java b/lib/taskana-core/src/test/java/acceptance/builder/WorkbasketAccessItemBuilderTest.java new file mode 100644 index 000000000..28bb744af --- /dev/null +++ b/lib/taskana-core/src/test/java/acceptance/builder/WorkbasketAccessItemBuilderTest.java @@ -0,0 +1,152 @@ +package acceptance.builder; + +import static acceptance.DefaultTestEntities.defaultTestWorkbasket; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.AssertionsForClassTypes.assertThatCode; +import static pro.taskana.common.internal.util.CheckedSupplier.wrap; +import static pro.taskana.workbasket.internal.WorkbasketAccessItemBuilder.newWorkbasketAccessItem; + +import acceptance.FooBar; +import java.util.List; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; + +import pro.taskana.common.api.TaskanaEngine; +import pro.taskana.common.test.security.JaasExtension; +import pro.taskana.common.test.security.WithAccessId; +import pro.taskana.workbasket.api.WorkbasketPermission; +import pro.taskana.workbasket.api.WorkbasketService; +import pro.taskana.workbasket.api.models.Workbasket; +import pro.taskana.workbasket.api.models.WorkbasketAccessItem; +import pro.taskana.workbasket.internal.WorkbasketAccessItemBuilder; +import pro.taskana.workbasket.internal.models.WorkbasketAccessItemImpl; + +@ExtendWith(JaasExtension.class) +class WorkbasketAccessItemBuilderTest { + + private static WorkbasketService workbasketService; + private static TaskanaEngine taskanaEngine; + + @BeforeAll + @WithAccessId(user = "businessadmin") + static void setup() throws Exception { + taskanaEngine = FooBar.getTaskanaEngineForTests(); + workbasketService = taskanaEngine.getWorkbasketService(); + } + + @WithAccessId(user = "businessadmin") + @Test + void should_PersistWorkbasketAccessItem_When_UsingWorkbasketAccessItemBuilder() throws Exception { + Workbasket workbasket = defaultTestWorkbasket().key("key0_F").buildAndStore(workbasketService); + + WorkbasketAccessItem workbasketAccessItem = + newWorkbasketAccessItem() + .workbasketId(workbasket.getId()) + .accessId("user-1-1") + .permission(WorkbasketPermission.READ) + .buildAndStore(workbasketService); + + List workbasketAccessItems = + workbasketService.getWorkbasketAccessItems(workbasket.getId()); + + assertThat(workbasketAccessItems).containsExactly(workbasketAccessItem); + } + + @Test + void should_PersistWorkbasketAccessItemAsUser_When_UsingWorkbasketAccessItemBuilder() + throws Exception { + Workbasket workbasket = + defaultTestWorkbasket().key("key1_F").buildAndStore(workbasketService, "businessadmin"); + + WorkbasketAccessItem workbasketAccessItem = + newWorkbasketAccessItem() + .workbasketId(workbasket.getId()) + .accessId("user-1-1") + .permission(WorkbasketPermission.READ) + .buildAndStore(workbasketService, "businessadmin"); + + List workbasketAccessItems = + taskanaEngine.runAsAdmin( + wrap(() -> workbasketService.getWorkbasketAccessItems(workbasket.getId()))); + + assertThat(workbasketAccessItems).containsExactly(workbasketAccessItem); + } + + @WithAccessId(user = "businessadmin") + @Test + void should_PopulateWorkbasketAccessItem_When_UsingEveryBuilderFunction() throws Exception { + Workbasket workbasket = defaultTestWorkbasket().key("key2_F").buildAndStore(workbasketService); + + WorkbasketAccessItemImpl expectedWorkbasketAccessItem = + (WorkbasketAccessItemImpl) + workbasketService.newWorkbasketAccessItem(workbasket.getId(), "user-1-1"); + expectedWorkbasketAccessItem.setWorkbasketKey(workbasket.getKey()); + expectedWorkbasketAccessItem.setAccessName("Max Mustermann"); + expectedWorkbasketAccessItem.setPermission(WorkbasketPermission.READ, true); + expectedWorkbasketAccessItem.setPermission(WorkbasketPermission.OPEN, true); + expectedWorkbasketAccessItem.setPermission(WorkbasketPermission.APPEND, true); + expectedWorkbasketAccessItem.setPermission(WorkbasketPermission.TRANSFER, true); + expectedWorkbasketAccessItem.setPermission(WorkbasketPermission.DISTRIBUTE, true); + expectedWorkbasketAccessItem.setPermission(WorkbasketPermission.CUSTOM_1, true); + expectedWorkbasketAccessItem.setPermission(WorkbasketPermission.CUSTOM_2, true); + expectedWorkbasketAccessItem.setPermission(WorkbasketPermission.CUSTOM_3, true); + expectedWorkbasketAccessItem.setPermission(WorkbasketPermission.CUSTOM_4, true); + expectedWorkbasketAccessItem.setPermission(WorkbasketPermission.CUSTOM_5, true); + expectedWorkbasketAccessItem.setPermission(WorkbasketPermission.CUSTOM_6, true); + expectedWorkbasketAccessItem.setPermission(WorkbasketPermission.CUSTOM_7, true); + expectedWorkbasketAccessItem.setPermission(WorkbasketPermission.CUSTOM_8, true); + expectedWorkbasketAccessItem.setPermission(WorkbasketPermission.CUSTOM_9, true); + expectedWorkbasketAccessItem.setPermission(WorkbasketPermission.CUSTOM_10, true); + expectedWorkbasketAccessItem.setPermission(WorkbasketPermission.CUSTOM_11, true); + expectedWorkbasketAccessItem.setPermission(WorkbasketPermission.CUSTOM_12, true); + + WorkbasketAccessItem accessItem = + newWorkbasketAccessItem() + .workbasketId(workbasket.getId()) + .accessId("user-1-1") + .accessName("Max Mustermann") + .permission(WorkbasketPermission.READ) + .permission(WorkbasketPermission.OPEN) + .permission(WorkbasketPermission.APPEND) + .permission(WorkbasketPermission.TRANSFER) + .permission(WorkbasketPermission.DISTRIBUTE) + .permission(WorkbasketPermission.CUSTOM_1) + .permission(WorkbasketPermission.CUSTOM_2) + .permission(WorkbasketPermission.CUSTOM_3) + .permission(WorkbasketPermission.CUSTOM_4) + .permission(WorkbasketPermission.CUSTOM_5) + .permission(WorkbasketPermission.CUSTOM_6) + .permission(WorkbasketPermission.CUSTOM_7) + .permission(WorkbasketPermission.CUSTOM_8) + .permission(WorkbasketPermission.CUSTOM_9) + .permission(WorkbasketPermission.CUSTOM_10) + .permission(WorkbasketPermission.CUSTOM_11) + .permission(WorkbasketPermission.CUSTOM_12) + .buildAndStore(workbasketService); + + assertThat(accessItem) + .hasNoNullFieldsOrProperties() + .usingRecursiveComparison() + .ignoringFields("id") + .isEqualTo(expectedWorkbasketAccessItem); + } + + @WithAccessId(user = "businessadmin") + @Test + void should_ResetClassificationId_When_StoringClassificationMultipleTimes() throws Exception { + Workbasket workbasket = defaultTestWorkbasket().key("key3_F").buildAndStore(workbasketService); + + WorkbasketAccessItemBuilder workbasketAccessItemBuilder = + newWorkbasketAccessItem() + .workbasketId(workbasket.getId()) + .permission(WorkbasketPermission.READ); + + assertThatCode( + () -> { + workbasketAccessItemBuilder.accessId("hanspeter").buildAndStore(workbasketService); + workbasketAccessItemBuilder.accessId("hanspeter2").buildAndStore(workbasketService); + }) + .doesNotThrowAnyException(); + } +} diff --git a/lib/taskana-core/src/test/java/acceptance/builder/WorkbasketBuilderTest.java b/lib/taskana-core/src/test/java/acceptance/builder/WorkbasketBuilderTest.java new file mode 100644 index 000000000..912b21462 --- /dev/null +++ b/lib/taskana-core/src/test/java/acceptance/builder/WorkbasketBuilderTest.java @@ -0,0 +1,222 @@ +package acceptance.builder; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatCode; +import static pro.taskana.common.internal.util.CheckedSupplier.wrap; +import static pro.taskana.workbasket.internal.WorkbasketBuilder.newWorkbasket; + +import acceptance.FooBar; +import java.time.Instant; +import java.util.List; +import java.util.function.BiFunction; +import java.util.function.Function; +import java.util.stream.Stream; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.DynamicContainer; +import org.junit.jupiter.api.DynamicTest; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestFactory; +import org.junit.jupiter.api.extension.ExtendWith; + +import pro.taskana.common.api.TaskanaEngine; +import pro.taskana.common.internal.util.Quadruple; +import pro.taskana.common.test.security.JaasExtension; +import pro.taskana.common.test.security.WithAccessId; +import pro.taskana.workbasket.api.WorkbasketCustomField; +import pro.taskana.workbasket.api.WorkbasketService; +import pro.taskana.workbasket.api.WorkbasketType; +import pro.taskana.workbasket.api.models.Workbasket; +import pro.taskana.workbasket.internal.WorkbasketBuilder; +import pro.taskana.workbasket.internal.models.WorkbasketImpl; + +@ExtendWith(JaasExtension.class) +class WorkbasketBuilderTest { + + private static WorkbasketService workbasketService; + private static TaskanaEngine taskanaEngine; + + @BeforeAll + static void setup() throws Exception { + taskanaEngine = FooBar.getTaskanaEngineForTests(); + workbasketService = taskanaEngine.getWorkbasketService(); + } + + @WithAccessId(user = "businessadmin") + @Test + void should_PersistWorkbasket_When_UsingWorkbasketBuilder() throws Exception { + Workbasket workbasket = + newWorkbasket() + .key("key0_G") + .domain("DOMAIN_A") + .name("Megabasket") + .type(WorkbasketType.GROUP) + .buildAndStore(workbasketService); + Workbasket receivedWorkbasket = workbasketService.getWorkbasket(workbasket.getId()); + assertThat(receivedWorkbasket).isEqualTo(workbasket); + } + + @Test + void should_PersistWorkbasketAsUser_When_UsingWorkbasketBuilder() throws Exception { + Workbasket workbasket = + newWorkbasket() + .domain("DOMAIN_A") + .description("PPK User 2 KSC 1") + .name("PPK User 2 KSC 1") + .key("key1_G") + .type(WorkbasketType.GROUP) + .buildAndStore(workbasketService, "businessadmin"); + + Workbasket receivedWorkbasket = + taskanaEngine.runAsAdmin(wrap(() -> workbasketService.getWorkbasket(workbasket.getId()))); + assertThat(receivedWorkbasket).isEqualTo(workbasket); + } + + @WithAccessId(user = "businessadmin") + @Test + void should_PopulateWorkbasket_When_UsingEveryBuilderFunction() throws Exception { + final Workbasket workbasket = + newWorkbasket() + .key("new_workbasket_key") + .name("This is a new workbasket") + .description("A test description") + .owner("user-1-1") + .domain("DOMAIN_A") + .type(WorkbasketType.PERSONAL) + .customAttribute(WorkbasketCustomField.CUSTOM_1, "custom 1 value") + .customAttribute(WorkbasketCustomField.CUSTOM_2, "custom 2 value") + .customAttribute(WorkbasketCustomField.CUSTOM_3, "custom 3 value") + .customAttribute(WorkbasketCustomField.CUSTOM_4, "custom 4 value") + .orgLevel1("org level 1") + .orgLevel2("org level 2") + .orgLevel3("org level 3") + .orgLevel4("org level 4") + .markedForDeletion(true) + .created(Instant.parse("2021-05-17T07:16:26.747Z")) + .modified(Instant.parse("2021-05-18T07:16:26.747Z")) + .buildAndStore(workbasketService); + + WorkbasketImpl expectedWorkbasket = + (WorkbasketImpl) workbasketService.newWorkbasket("new_workbasket_key", "DOMAIN_A"); + expectedWorkbasket.setName("This is a new workbasket"); + expectedWorkbasket.setDescription("A test description"); + expectedWorkbasket.setOwner("user-1-1"); + expectedWorkbasket.setType(WorkbasketType.PERSONAL); + expectedWorkbasket.setCustomAttribute(WorkbasketCustomField.CUSTOM_1, "custom 1 value"); + expectedWorkbasket.setCustomAttribute(WorkbasketCustomField.CUSTOM_2, "custom 2 value"); + expectedWorkbasket.setCustomAttribute(WorkbasketCustomField.CUSTOM_3, "custom 3 value"); + expectedWorkbasket.setCustomAttribute(WorkbasketCustomField.CUSTOM_4, "custom 4 value"); + expectedWorkbasket.setOrgLevel1("org level 1"); + expectedWorkbasket.setOrgLevel2("org level 2"); + expectedWorkbasket.setOrgLevel3("org level 3"); + expectedWorkbasket.setOrgLevel4("org level 4"); + expectedWorkbasket.setMarkedForDeletion(true); + expectedWorkbasket.setCreated(Instant.parse("2021-05-17T07:16:26.747Z")); + expectedWorkbasket.setModified(Instant.parse("2021-05-18T07:16:26.747Z")); + + assertThat(workbasket) + .hasNoNullFieldsOrProperties() + .usingRecursiveComparison() + .ignoringFields("id") + .isEqualTo(expectedWorkbasket); + } + + @WithAccessId(user = "businessadmin") + @Test + void should_ResetWorkbasketId_When_StoringWorkbasketMultipleTimes() { + Instant created = Instant.parse("2021-05-17T07:16:25.747Z"); + + WorkbasketBuilder builder = + newWorkbasket() + .domain("DOMAIN_A") + .name("Megabasket") + .type(WorkbasketType.GROUP) + .created(created); + assertThatCode( + () -> { + builder.key("key4_G").buildAndStore(workbasketService); + builder.key("key5_G").buildAndStore(workbasketService); + }) + .doesNotThrowAnyException(); + } + + @WithAccessId(user = "businessadmin") + @TestFactory + Stream should_PersistWorkbasket_When_CreatingEntityWithInvalidApiValues() { + List< + Quadruple< + String, + Object, + BiFunction, + Function>> + list = + List.of( + Quadruple.of( + "created", + Instant.parse("2020-05-17T07:16:26.747Z"), + (b, v) -> b.created((Instant) v), + Workbasket::getCreated), + Quadruple.of( + "modified", + Instant.parse("2019-05-17T07:16:26.747Z"), + (b, v) -> b.modified((Instant) v), + Workbasket::getModified)); + + Stream applyBuilderFunction = + DynamicTest.stream( + list.iterator(), + q -> String.format("for field: '%s'", q.getFirst()), + q -> applyBuilderFunctionAndVerifyValue(q.getSecond(), q.getThird(), q.getFourth())); + + Stream overrideBuilderFunctionWithApiDefault = + DynamicTest.stream( + list.iterator(), + q -> String.format("for field: '%s'", q.getFirst()), + t -> applyAndOverrideWithApiDefaultValue(t.getSecond(), t.getThird(), t.getFourth())); + + return Stream.of( + DynamicContainer.dynamicContainer( + "set values which are invalid through API", applyBuilderFunction), + DynamicContainer.dynamicContainer( + "override with API default value", overrideBuilderFunctionWithApiDefault)); + } + + private void applyBuilderFunctionAndVerifyValue( + T value, + BiFunction builderfunction, + Function retriever) + throws Exception { + WorkbasketBuilder builder = + newWorkbasket() + .domain("DOMAIN_A") + .name("workbasketName") + .type(WorkbasketType.PERSONAL) + .key("A" + builderfunction.hashCode()); + + builderfunction.apply(builder, value); + Workbasket classification = builder.buildAndStore(workbasketService); + T retrievedValue = retriever.apply(classification); + + assertThat(retrievedValue).isEqualTo(value); + } + + private void applyAndOverrideWithApiDefaultValue( + T value, + BiFunction builderfunction, + Function retriever) + throws Exception { + WorkbasketBuilder builder = + newWorkbasket() + .domain("DOMAIN_A") + .name("workbasketName") + .type(WorkbasketType.PERSONAL) + .key("B" + builderfunction.hashCode()); + + builderfunction.apply(builder, value); + builderfunction.apply(builder, null); + + Workbasket classification = builder.buildAndStore(workbasketService); + T retrievedValue = retriever.apply(classification); + + assertThat(retrievedValue).isNotNull().isNotEqualTo(value); + } +} diff --git a/lib/taskana-core/src/test/java/acceptance/config/TaskanaConfigAccTest.java b/lib/taskana-core/src/test/java/acceptance/config/TaskanaConfigAccTest.java index 36ef04fd2..519981024 100644 --- a/lib/taskana-core/src/test/java/acceptance/config/TaskanaConfigAccTest.java +++ b/lib/taskana-core/src/test/java/acceptance/config/TaskanaConfigAccTest.java @@ -2,7 +2,6 @@ package acceptance.config; import static org.assertj.core.api.Assertions.assertThat; -import acceptance.TaskanaEngineTestConfiguration; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; @@ -16,6 +15,7 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.io.TempDir; import pro.taskana.TaskanaEngineConfiguration; +import pro.taskana.common.test.config.DataSourceGenerator; /** Test taskana configuration without roles. */ class TaskanaConfigAccTest { @@ -27,9 +27,7 @@ class TaskanaConfigAccTest { void setup() { taskanaEngineConfiguration = new TaskanaEngineConfiguration( - TaskanaEngineTestConfiguration.getDataSource(), - true, - TaskanaEngineTestConfiguration.getSchemaName()); + DataSourceGenerator.getDataSource(), true, DataSourceGenerator.getSchemaName()); } @Test @@ -56,12 +54,12 @@ class TaskanaConfigAccTest { String delimiter = ";"; taskanaEngineConfiguration = new TaskanaEngineConfiguration( - TaskanaEngineTestConfiguration.getDataSource(), + DataSourceGenerator.getDataSource(), true, true, propertiesFileName, delimiter, - TaskanaEngineTestConfiguration.getSchemaName()); + DataSourceGenerator.getSchemaName()); assertThat(taskanaEngineConfiguration.getClassificationTypes()).isEmpty(); } @@ -71,12 +69,12 @@ class TaskanaConfigAccTest { String delimiter = ";"; taskanaEngineConfiguration = new TaskanaEngineConfiguration( - TaskanaEngineTestConfiguration.getDataSource(), + DataSourceGenerator.getDataSource(), true, true, propertiesFileName, delimiter, - TaskanaEngineTestConfiguration.getSchemaName()); + DataSourceGenerator.getSchemaName()); assertThat(taskanaEngineConfiguration.getClassificationCategoriesByTypeMap()) .containsExactly( Map.entry("TASK", Collections.emptyList()), @@ -89,12 +87,12 @@ class TaskanaConfigAccTest { String delimiter = ";"; taskanaEngineConfiguration = new TaskanaEngineConfiguration( - TaskanaEngineTestConfiguration.getDataSource(), + DataSourceGenerator.getDataSource(), true, true, propertiesFileName, delimiter, - TaskanaEngineTestConfiguration.getSchemaName()); + DataSourceGenerator.getSchemaName()); assertThat(taskanaEngineConfiguration.getClassificationCategoriesByTypeMap()) .containsExactly( Map.entry("TASK", List.of("EXTERNAL", "MANUAL", "AUTOMATIC", "PROCESS")), diff --git a/lib/taskana-core/src/test/java/acceptance/config/TaskanaEngineConfigTest.java b/lib/taskana-core/src/test/java/acceptance/config/TaskanaEngineConfigTest.java index c597a0c66..ea42917c9 100644 --- a/lib/taskana-core/src/test/java/acceptance/config/TaskanaEngineConfigTest.java +++ b/lib/taskana-core/src/test/java/acceptance/config/TaskanaEngineConfigTest.java @@ -2,22 +2,22 @@ package acceptance.config; import static org.assertj.core.api.Assertions.assertThat; -import acceptance.TaskanaEngineTestConfiguration; import javax.sql.DataSource; import org.junit.jupiter.api.Test; import pro.taskana.TaskanaEngineConfiguration; import pro.taskana.common.api.CustomHoliday; import pro.taskana.common.api.TaskanaEngine; +import pro.taskana.common.test.config.DataSourceGenerator; /** Test of configuration. */ class TaskanaEngineConfigTest { @Test void should_ReturnTaskanaEngine_When_BuildingWithConfiguration() throws Exception { - DataSource ds = TaskanaEngineTestConfiguration.getDataSource(); + DataSource ds = DataSourceGenerator.getDataSource(); TaskanaEngineConfiguration taskEngineConfiguration = - new TaskanaEngineConfiguration(ds, false, TaskanaEngineTestConfiguration.getSchemaName()); + new TaskanaEngineConfiguration(ds, false, DataSourceGenerator.getSchemaName()); TaskanaEngine te = taskEngineConfiguration.buildTaskanaEngine(); @@ -26,7 +26,7 @@ class TaskanaEngineConfigTest { @Test void should_SetCorpusChristiEnabled_When_PropertyIsSet() throws Exception { - DataSource ds = TaskanaEngineTestConfiguration.getDataSource(); + DataSource ds = DataSourceGenerator.getDataSource(); TaskanaEngineConfiguration taskEngineConfiguration = new TaskanaEngineConfiguration( ds, @@ -34,7 +34,7 @@ class TaskanaEngineConfigTest { true, "/corpusChristiEnabled.properties", "|", - TaskanaEngineTestConfiguration.getSchemaName()); + DataSourceGenerator.getSchemaName()); assertThat(taskEngineConfiguration.isCorpusChristiEnabled()).isTrue(); } @@ -42,7 +42,7 @@ class TaskanaEngineConfigTest { @Test void should_ReturnTheTwoCustomHolidays_When_TwoCustomHolidaysAreConfiguredInThePropertiesFile() throws Exception { - DataSource ds = TaskanaEngineTestConfiguration.getDataSource(); + DataSource ds = DataSourceGenerator.getDataSource(); TaskanaEngineConfiguration taskEngineConfiguration = new TaskanaEngineConfiguration( ds, @@ -50,7 +50,7 @@ class TaskanaEngineConfigTest { true, "/custom_holiday_taskana.properties", "|", - TaskanaEngineTestConfiguration.getSchemaName()); + DataSourceGenerator.getSchemaName()); assertThat(taskEngineConfiguration.getCustomHolidays()).contains(CustomHoliday.of(31, 7)); assertThat(taskEngineConfiguration.getCustomHolidays()).contains(CustomHoliday.of(16, 12)); } @@ -58,7 +58,7 @@ class TaskanaEngineConfigTest { @Test void should_ReturnEmptyCustomHolidaysList_When_AllCustomHolidaysAreInWrongFormatInPropertiesFile() throws Exception { - DataSource ds = TaskanaEngineTestConfiguration.getDataSource(); + DataSource ds = DataSourceGenerator.getDataSource(); TaskanaEngineConfiguration taskEngineConfiguration = new TaskanaEngineConfiguration( ds, @@ -66,7 +66,7 @@ class TaskanaEngineConfigTest { true, "/custom_holiday_with_wrong_format_taskana.properties", "|", - TaskanaEngineTestConfiguration.getSchemaName()); + DataSourceGenerator.getSchemaName()); assertThat(taskEngineConfiguration.getCustomHolidays()).isEmpty(); } } diff --git a/lib/taskana-core/src/test/java/acceptance/config/TaskanaRoleConfigAccTest.java b/lib/taskana-core/src/test/java/acceptance/config/TaskanaRoleConfigAccTest.java index 8b19116ed..7b94581b8 100644 --- a/lib/taskana-core/src/test/java/acceptance/config/TaskanaRoleConfigAccTest.java +++ b/lib/taskana-core/src/test/java/acceptance/config/TaskanaRoleConfigAccTest.java @@ -2,7 +2,6 @@ package acceptance.config; import static org.assertj.core.api.Assertions.assertThat; -import acceptance.TaskanaEngineTestConfiguration; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; @@ -14,6 +13,7 @@ import org.junit.jupiter.api.io.TempDir; import pro.taskana.TaskanaEngineConfiguration; import pro.taskana.common.api.TaskanaRole; +import pro.taskana.common.test.config.DataSourceGenerator; /** Test taskana's role configuration. */ class TaskanaRoleConfigAccTest { @@ -25,9 +25,7 @@ class TaskanaRoleConfigAccTest { void setup() { taskanaEngineConfiguration = new TaskanaEngineConfiguration( - TaskanaEngineTestConfiguration.getDataSource(), - true, - TaskanaEngineTestConfiguration.getSchemaName()); + DataSourceGenerator.getDataSource(), true, DataSourceGenerator.getSchemaName()); } @Test @@ -71,12 +69,12 @@ class TaskanaRoleConfigAccTest { String delimiter = "|"; taskanaEngineConfiguration = new TaskanaEngineConfiguration( - TaskanaEngineTestConfiguration.getDataSource(), + DataSourceGenerator.getDataSource(), true, true, propertiesFileName, delimiter, - TaskanaEngineTestConfiguration.getSchemaName()); + DataSourceGenerator.getSchemaName()); Set rolesConfigured = taskanaEngineConfiguration.getRoleMap().keySet(); assertThat(rolesConfigured).containsExactlyInAnyOrder(TaskanaRole.values()); @@ -103,12 +101,12 @@ class TaskanaRoleConfigAccTest { taskanaEngineConfiguration = new TaskanaEngineConfiguration( - TaskanaEngineTestConfiguration.getDataSource(), + DataSourceGenerator.getDataSource(), true, true, propertiesFileName, delimiter, - TaskanaEngineTestConfiguration.getSchemaName()); + DataSourceGenerator.getSchemaName()); Set rolesConfigured = taskanaEngineConfiguration.getRoleMap().keySet(); assertThat(rolesConfigured).containsExactlyInAnyOrder(TaskanaRole.values()); diff --git a/lib/taskana-core/src/test/java/acceptance/config/TaskanaSecurityConfigAccTest.java b/lib/taskana-core/src/test/java/acceptance/config/TaskanaSecurityConfigAccTest.java index 720d5b2a8..b3defb469 100644 --- a/lib/taskana-core/src/test/java/acceptance/config/TaskanaSecurityConfigAccTest.java +++ b/lib/taskana-core/src/test/java/acceptance/config/TaskanaSecurityConfigAccTest.java @@ -4,7 +4,6 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatCode; import static org.assertj.core.api.Assertions.assertThatThrownBy; -import acceptance.TaskanaEngineTestConfiguration; import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; @@ -17,14 +16,15 @@ import pro.taskana.TaskanaEngineConfiguration; import pro.taskana.common.api.exceptions.SystemException; import pro.taskana.common.internal.configuration.DbSchemaCreator; import pro.taskana.common.internal.configuration.SecurityVerifier; +import pro.taskana.common.test.config.DataSourceGenerator; import pro.taskana.sampledata.SampleDataGenerator; class TaskanaSecurityConfigAccTest { @BeforeEach void cleanDb() throws Exception { - DataSource dataSource = TaskanaEngineTestConfiguration.getDataSource(); - String schemaName = TaskanaEngineTestConfiguration.getSchemaName(); + DataSource dataSource = DataSourceGenerator.getDataSource(); + String schemaName = DataSourceGenerator.getSchemaName(); DbSchemaCreator dbSchemaCreator = new DbSchemaCreator(dataSource, schemaName); dbSchemaCreator.run(); @@ -76,22 +76,22 @@ class TaskanaSecurityConfigAccTest { private void createTaskanaEngine(boolean securityEnabled) throws SQLException { new TaskanaEngineConfiguration( - TaskanaEngineTestConfiguration.getDataSource(), + DataSourceGenerator.getDataSource(), false, securityEnabled, - TaskanaEngineTestConfiguration.getSchemaName()) + DataSourceGenerator.getSchemaName()) .buildTaskanaEngine(); } private Boolean retrieveSecurityFlag() throws Exception { - try (Connection connection = TaskanaEngineTestConfiguration.getDataSource().getConnection()) { + try (Connection connection = DataSourceGenerator.getDataSource().getConnection()) { String selectSecurityFlagSql = String.format( SecurityVerifier.SELECT_SECURITY_FLAG_SQL, SecurityVerifier.SECURITY_FLAG_COLUMN_NAME, - TaskanaEngineTestConfiguration.getSchemaName()); + DataSourceGenerator.getSchemaName()); Statement statement = connection.createStatement(); ResultSet resultSet = statement.executeQuery(selectSecurityFlagSql); @@ -106,12 +106,12 @@ class TaskanaSecurityConfigAccTest { private void setSecurityFlag(boolean securityFlag) throws Exception { - try (Connection connection = TaskanaEngineTestConfiguration.getDataSource().getConnection()) { + try (Connection connection = DataSourceGenerator.getDataSource().getConnection()) { String sql = String.format( SecurityVerifier.INSERT_SECURITY_FLAG_SQL, - TaskanaEngineTestConfiguration.getSchemaName(), + DataSourceGenerator.getSchemaName(), securityFlag); Statement statement = connection.createStatement(); diff --git a/lib/taskana-core/src/test/java/acceptance/jobs/JobRunnerAccTest.java b/lib/taskana-core/src/test/java/acceptance/jobs/JobRunnerAccTest.java index 5361a52ab..c37f8bb06 100644 --- a/lib/taskana-core/src/test/java/acceptance/jobs/JobRunnerAccTest.java +++ b/lib/taskana-core/src/test/java/acceptance/jobs/JobRunnerAccTest.java @@ -3,7 +3,6 @@ package acceptance.jobs; import static org.assertj.core.api.Assertions.assertThat; import acceptance.AbstractAccTest; -import acceptance.TaskanaEngineTestConfiguration; import java.sql.Connection; import java.time.Instant; import java.time.temporal.ChronoUnit; @@ -21,6 +20,7 @@ import pro.taskana.common.api.exceptions.SystemException; import pro.taskana.common.internal.JobServiceImpl; import pro.taskana.common.internal.jobs.JobRunner; import pro.taskana.common.internal.jobs.PlainJavaTransactionProvider; +import pro.taskana.common.test.config.DataSourceGenerator; import pro.taskana.task.internal.jobs.TaskCleanupJob; class JobRunnerAccTest extends AbstractAccTest { @@ -40,7 +40,7 @@ class JobRunnerAccTest extends AbstractAccTest { try { TaskanaEngine taskanaEngine = taskanaEngineConfiguration.buildTaskanaEngine(); taskanaEngine.setConnectionManagementMode(ConnectionManagementMode.AUTOCOMMIT); - DataSource dataSource = TaskanaEngineTestConfiguration.getDataSource(); + DataSource dataSource = DataSourceGenerator.getDataSource(); // We have to slow down the transaction. // This is necessary to guarantee the execution of // both test threads and therefore test the database lock. diff --git a/lib/taskana-core/src/test/java/acceptance/report/AbstractReportAccTest.java b/lib/taskana-core/src/test/java/acceptance/report/AbstractReportAccTest.java index 829fbdcc9..5a969c1fa 100644 --- a/lib/taskana-core/src/test/java/acceptance/report/AbstractReportAccTest.java +++ b/lib/taskana-core/src/test/java/acceptance/report/AbstractReportAccTest.java @@ -1,11 +1,11 @@ package acceptance.report; -import acceptance.TaskanaEngineTestConfiguration; import javax.sql.DataSource; import org.junit.jupiter.api.BeforeAll; import pro.taskana.TaskanaEngineConfiguration; import pro.taskana.common.api.TaskanaEngine; +import pro.taskana.common.test.config.DataSourceGenerator; import pro.taskana.sampledata.SampleDataGenerator; /** Abstract test class for all report building tests. */ @@ -15,8 +15,8 @@ public abstract class AbstractReportAccTest { protected static TaskanaEngine taskanaEngine; protected static void resetDb() throws Exception { - DataSource dataSource = TaskanaEngineTestConfiguration.getDataSource(); - String schemaName = TaskanaEngineTestConfiguration.getSchemaName(); + DataSource dataSource = DataSourceGenerator.getDataSource(); + String schemaName = DataSourceGenerator.getSchemaName(); taskanaEngineConfiguration = new TaskanaEngineConfiguration(dataSource, false, schemaName); taskanaEngineConfiguration.setGermanPublicHolidaysEnabled(false); taskanaEngine = taskanaEngineConfiguration.buildTaskanaEngine(); diff --git a/lib/taskana-core/src/test/java/acceptance/task/CreateTaskAccTest.java b/lib/taskana-core/src/test/java/acceptance/task/CreateTaskAccTest.java index 11c54a092..dbae97674 100644 --- a/lib/taskana-core/src/test/java/acceptance/task/CreateTaskAccTest.java +++ b/lib/taskana-core/src/test/java/acceptance/task/CreateTaskAccTest.java @@ -755,6 +755,15 @@ class CreateTaskAccTest extends AbstractAccTest { assertThatThrownBy(call).isInstanceOf(NotAuthorizedException.class); } + @WithAccessId(user = "user-1-1") + @Test + void should_NotThrowNullPointerException_When_CreatingTaskWithoutWorkbasketSummary() { + Task task = new TaskImpl(); + + ThrowingCallable call = () -> taskService.createTask(task); + assertThatThrownBy(call).isInstanceOf(InvalidArgumentException.class); + } + @WithAccessId(user = "admin") @Test void testCreateTaskWithWorkbasketMarkedForDeletion() throws Exception { diff --git a/routing/taskana-spi-routing-dmn-router/src/test/java/pro/taskana/AbstractAccTest.java b/routing/taskana-spi-routing-dmn-router/src/test/java/pro/taskana/AbstractAccTest.java index fe21487b9..8d11a3c13 100644 --- a/routing/taskana-spi-routing-dmn-router/src/test/java/pro/taskana/AbstractAccTest.java +++ b/routing/taskana-spi-routing-dmn-router/src/test/java/pro/taskana/AbstractAccTest.java @@ -7,7 +7,7 @@ import pro.taskana.common.api.TaskanaEngine; import pro.taskana.common.api.TaskanaEngine.ConnectionManagementMode; import pro.taskana.common.api.WorkingDaysToDaysConverter; import pro.taskana.common.internal.configuration.DbSchemaCreator; -import pro.taskana.common.test.config.TaskanaEngineTestConfiguration; +import pro.taskana.common.test.config.DataSourceGenerator; import pro.taskana.sampledata.SampleDataGenerator; import pro.taskana.task.api.models.ObjectReference; @@ -24,13 +24,13 @@ public abstract class AbstractAccTest { protected static void resetDb(boolean dropTables) throws Exception { - DataSource dataSource = TaskanaEngineTestConfiguration.getDataSource(); - String schemaName = TaskanaEngineTestConfiguration.getSchemaName(); + DataSource dataSource = DataSourceGenerator.getDataSource(); + String schemaName = DataSourceGenerator.getSchemaName(); SampleDataGenerator sampleDataGenerator = new SampleDataGenerator(dataSource, schemaName); if (dropTables) { sampleDataGenerator.dropDb(); } - dataSource = TaskanaEngineTestConfiguration.getDataSource(); + dataSource = DataSourceGenerator.getDataSource(); taskanaEngineConfiguration = new TaskanaEngineConfiguration(dataSource, false, schemaName); taskanaEngineConfiguration.setGermanPublicHolidaysEnabled(true); DbSchemaCreator dbSchemaCreator =