TSK-1286: refactored WorkingDaysToDaysConverter

This commit is contained in:
Mustapha Zorgati 2020-06-11 14:54:21 +02:00
parent ca2d82ce3a
commit 02e05a7d3b
27 changed files with 647 additions and 874 deletions

View File

@ -54,6 +54,13 @@ public interface TaskanaEngine {
*/
TaskanaEngineConfiguration getConfiguration();
/**
* The WorkingDaysToDaysConverter used to compute holidays.
*
* @return the converter
*/
WorkingDaysToDaysConverter getWorkingDaysToDaysConverter();
/**
* Checks if the history plugin is enabled.
*

View File

@ -0,0 +1,217 @@
package pro.taskana.common.api;
import static java.time.temporal.ChronoUnit.DAYS;
import java.time.DayOfWeek;
import java.time.Duration;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import java.util.stream.LongStream;
import java.util.stream.LongStream.Builder;
import pro.taskana.common.api.exceptions.SystemException;
/**
* The WorkingDaysToDaysConverter provides a method to convert an age in working days into an age in
* days.
*/
public final class WorkingDaysToDaysConverter {
// offset in days from easter sunday
private static final long OFFSET_GOOD_FRIDAY = -2; // Good Friday
private static final long OFFSET_EASTER_MONDAY = 1; // Easter Monday
private static final long OFFSET_ASCENSION_DAY = 39; // Ascension Day
private static final long OFFSET_WHIT_MONDAY = 50; // Whit Monday
private static final long OFFSET_CORPUS_CHRISTI = 60; // Corpus Christi
private static final Set<CustomHoliday> GERMAN_HOLIDAYS =
new HashSet<>(
Arrays.asList(
CustomHoliday.of(1, 1), // New Year
CustomHoliday.of(1, 5), // Labour Day
CustomHoliday.of(3, 10), // German Unity Day
CustomHoliday.of(25, 12), // Christmas Day
CustomHoliday.of(26, 12) // Christmas Day
));
private final boolean germanHolidaysEnabled;
private final boolean corpusChristiEnabled;
private final Set<CustomHoliday> customHolidays;
private final EasterCalculator easterCalculator;
public WorkingDaysToDaysConverter(boolean germanHolidaysEnabled, boolean corpusChristiEnabled) {
this(germanHolidaysEnabled, corpusChristiEnabled, Collections.emptySet());
}
/**
* Creates a WorkingDasToDaysConverter.
*
* @param germanHolidaysEnabled identifier for German holidays
* @param corpusChristiEnabled identifier for Corpus Christi - dependent from
* germanHolidaysEnabled and thus only validated if German holidays are enabled.
* @param customHolidays additional custom holidays
*/
public WorkingDaysToDaysConverter(
boolean germanHolidaysEnabled,
boolean corpusChristiEnabled,
Collection<CustomHoliday> customHolidays) {
this.germanHolidaysEnabled = germanHolidaysEnabled;
this.corpusChristiEnabled = corpusChristiEnabled;
this.customHolidays = new HashSet<>(customHolidays);
easterCalculator = new EasterCalculator();
}
public Instant addWorkingDaysToInstant(Instant instant, Duration workingDays) {
long days = convertWorkingDaysToDays(instant, workingDays.toDays(), ZeroDirection.ADD_DAYS);
return instant.plus(Duration.ofDays(days));
}
public Instant subtractWorkingDaysFromInstant(Instant instant, Duration workingDays) {
long days = convertWorkingDaysToDays(instant, -workingDays.toDays(), ZeroDirection.SUB_DAYS);
return instant.plus(Duration.ofDays(days));
}
// counts working days between two dates, exclusive for both margins.
public boolean hasWorkingDaysInBetween(Instant left, Instant right) {
long days = Duration.between(left, right).abs().toDays();
Instant firstInstant = left.isBefore(right) ? left : right;
return LongStream.range(1, days).anyMatch(day -> isWorkingDay(firstInstant.plus(day, DAYS)));
}
public boolean isWorkingDay(Instant referenceDate) {
LocalDate dateToCheck =
LocalDateTime.ofInstant(referenceDate, ZoneId.systemDefault()).toLocalDate();
return !isWeekend(dateToCheck) && !isHoliday(dateToCheck);
}
public boolean isWeekend(LocalDate dateToCheck) {
return dateToCheck.getDayOfWeek().equals(DayOfWeek.SATURDAY)
|| dateToCheck.getDayOfWeek().equals(DayOfWeek.SUNDAY);
}
public boolean isHoliday(LocalDate date) {
if (germanHolidaysEnabled && isGermanHoliday(date)) {
return true;
}
// Custom holidays that can be configured in the TaskanaEngineConfiguration
return customHolidays.contains(CustomHoliday.of(date.getDayOfMonth(), date.getMonthValue()));
}
public boolean isGermanHoliday(LocalDate date) {
if (GERMAN_HOLIDAYS.contains(CustomHoliday.of(date.getDayOfMonth(), date.getMonthValue()))) {
return true;
}
// Easter holidays Good Friday, Easter Monday, Ascension Day, Whit Monday.
long diffFromEasterSunday =
DAYS.between(easterCalculator.getEasterSunday(date.getYear()), date);
Builder builder =
LongStream.builder()
.add(OFFSET_GOOD_FRIDAY)
.add(OFFSET_EASTER_MONDAY)
.add(OFFSET_ASCENSION_DAY)
.add(OFFSET_WHIT_MONDAY);
if (corpusChristiEnabled) {
builder.add(OFFSET_CORPUS_CHRISTI);
}
return builder.build().anyMatch(c -> c == diffFromEasterSunday);
}
private long convertWorkingDaysToDays(
final Instant startTime, long numberOfDays, ZeroDirection zeroDirection) {
if (startTime == null) {
throw new SystemException(
"Internal Error: convertWorkingDaysToDays was called with a null startTime");
}
int direction = calculateDirection(numberOfDays, zeroDirection);
long limit = Math.abs(numberOfDays);
return LongStream.iterate(0, i -> i + direction)
.filter(day -> isWorkingDay(startTime.plus(day, DAYS)))
.skip(limit)
.findFirst()
.orElse(0);
}
private int calculateDirection(long numberOfDays, ZeroDirection zeroDirection) {
if (numberOfDays == 0) {
return zeroDirection.getDirection();
} else {
return numberOfDays >= 0 ? 1 : -1;
}
}
@Override
public String toString() {
return "WorkingDaysToDaysConverter [germanHolidaysEnabled="
+ germanHolidaysEnabled
+ ", corpusChristiEnabled="
+ corpusChristiEnabled
+ ", customHolidays="
+ customHolidays
+ ", easterCalculator="
+ easterCalculator
+ "]";
}
private enum ZeroDirection {
SUB_DAYS(-1),
ADD_DAYS(1);
private final int direction;
ZeroDirection(int direction) {
this.direction = direction;
}
public int getDirection() {
return direction;
}
}
static class EasterCalculator {
LocalDate cachedEasterDay;
/**
* Computes the date of Easter Sunday for a given year.
*
* @param year for which the date of Easter Sunday should be calculated
* @return the date of Easter Sunday for the given year
*/
LocalDate getEasterSunday(int year) {
if (cachedEasterDay != null && cachedEasterDay.getYear() == year) {
return cachedEasterDay;
}
// Algorithm for calculating the date of Easter Sunday
// (Meeus/Jones/Butcher Gregorian algorithm)
// see https://dzone.com/articles/algorithm-calculating-date
int a = year % 19;
int b = year / 100;
int c = year % 100;
int d = b / 4;
int e = b % 4;
int f = (b + 8) / 25;
int g = (b - f + 1) / 3;
int h = (19 * a + b - d - g + 15) % 30;
int i = c / 4;
int k = c % 4;
int l = (32 + 2 * e + 2 * i - h - k) % 7;
int m = (a + 11 * h + 22 * l) / 451;
int n = h + l - 7 * m + 114;
int month = n / 31;
int day = (n % 31) + 1;
cachedEasterDay = LocalDate.of(year, month, day);
return cachedEasterDay;
}
}
}

View File

@ -35,6 +35,7 @@ import pro.taskana.classification.internal.ClassificationServiceImpl;
import pro.taskana.common.api.JobService;
import pro.taskana.common.api.TaskanaEngine;
import pro.taskana.common.api.TaskanaRole;
import pro.taskana.common.api.WorkingDaysToDaysConverter;
import pro.taskana.common.api.exceptions.AutocommitFailedException;
import pro.taskana.common.api.exceptions.ConnectionNotSetException;
import pro.taskana.common.api.exceptions.NotAuthorizedException;
@ -70,14 +71,15 @@ public class TaskanaEngineImpl implements TaskanaEngine {
private static final String DEFAULT = "default";
private static final Logger LOGGER = LoggerFactory.getLogger(TaskanaEngineImpl.class);
private static final SessionStack SESSION_STACK = new SessionStack();
private final HistoryEventProducer historyEventProducer;
private final TaskRoutingManager taskRoutingManager;
private final InternalTaskanaEngineImpl internalTaskanaEngineImpl;
private final WorkingDaysToDaysConverter workingDaysToDaysConverter;
protected TaskanaEngineConfiguration taskanaEngineConfiguration;
protected TransactionFactory transactionFactory;
protected SqlSessionManager sessionManager;
protected ConnectionManagementMode mode = ConnectionManagementMode.PARTICIPATE;
protected java.sql.Connection connection = null;
private final HistoryEventProducer historyEventProducer;
private final TaskRoutingManager taskRoutingManager;
private final InternalTaskanaEngineImpl internalTaskanaEngineImpl;
protected Connection connection = null;
protected TaskanaEngineImpl(TaskanaEngineConfiguration taskanaEngineConfiguration) {
this.taskanaEngineConfiguration = taskanaEngineConfiguration;
@ -86,6 +88,11 @@ public class TaskanaEngineImpl implements TaskanaEngine {
historyEventProducer = HistoryEventProducer.getInstance(taskanaEngineConfiguration);
taskRoutingManager = TaskRoutingManager.getInstance(this);
this.internalTaskanaEngineImpl = new InternalTaskanaEngineImpl();
workingDaysToDaysConverter =
new WorkingDaysToDaysConverter(
taskanaEngineConfiguration.isGermanPublicHolidaysEnabled(),
taskanaEngineConfiguration.isCorpusChristiEnabled(),
taskanaEngineConfiguration.getCustomHolidays());
}
public static TaskanaEngine createTaskanaEngine(
@ -140,6 +147,11 @@ public class TaskanaEngineImpl implements TaskanaEngine {
return this.taskanaEngineConfiguration;
}
@Override
public WorkingDaysToDaysConverter getWorkingDaysToDaysConverter() {
return workingDaysToDaysConverter;
}
@Override
public boolean isHistoryEnabled() {
return HistoryEventProducer.isHistoryEnabled();
@ -159,7 +171,7 @@ public class TaskanaEngineImpl implements TaskanaEngine {
}
@Override
public void setConnection(java.sql.Connection connection) throws SQLException {
public void setConnection(Connection connection) throws SQLException {
if (connection != null) {
this.connection = connection;
// disabling auto commit for passed connection in order to gain full control over the

View File

@ -1,258 +0,0 @@
package pro.taskana.common.internal.util;
import static java.time.temporal.ChronoUnit.DAYS;
import java.time.DayOfWeek;
import java.time.Duration;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.LongStream;
import java.util.stream.LongStream.Builder;
import pro.taskana.common.api.CustomHoliday;
import pro.taskana.common.api.exceptions.InvalidArgumentException;
import pro.taskana.common.api.exceptions.SystemException;
/**
* The WorkingDaysToDaysConverter provides a method to convert an age in working days into an age in
* days.
*/
public final class WorkingDaysToDaysConverter {
// offset in days from easter sunday
private static final long OFFSET_GOOD_FRIDAY = -2; // Karfreitag
private static final long OFFSET_EASTER_MONDAY = 1; // Ostermontag
private static final long OFFSET_ASCENSION_DAY = 39; // Himmelfahrt
private static final long OFFSET_WHIT_MONDAY = 50; // Pfingstmontag
private static final long OFFSET_CORPUS_CHRISTI = 60; // Fronleichnam
private static final Set<CustomHoliday> GERMAN_HOLIDAYS =
new HashSet<>(
Arrays.asList(
CustomHoliday.of(1, 1), // new year
CustomHoliday.of(1, 5), // labour day
CustomHoliday.of(3, 10), // german unity
CustomHoliday.of(25, 12), // Christmas
CustomHoliday.of(26, 12) // Christmas
));
private static boolean germanHolidaysEnabled;
private static boolean corpusChristiEnabled; // Fronleichnam
private static Set<CustomHoliday> customHolidays = new HashSet<>();
private Instant referenceDate;
private LocalDate easterSunday;
private WorkingDaysToDaysConverter(Instant referenceDate) {
easterSunday =
getEasterSunday(LocalDateTime.ofInstant(referenceDate, ZoneId.systemDefault()).getYear());
this.referenceDate = referenceDate;
}
public Instant getReferenceDate() {
return referenceDate;
}
/**
* Initializes the WorkingDaysToDaysConverter for the current day.
*
* @return an instance of the WorkingDaysToDaysConverter
* @throws SystemException is thrown when the {@link WorkingDaysToDaysConverter} cannot be
* initialized with the current Instant. Should never occur.
*/
public static WorkingDaysToDaysConverter initialize() {
try {
return initialize(Instant.now());
} catch (InvalidArgumentException ex) {
throw new SystemException(
"Internal error. Cannot initialize WorkingDaysToDaysConverter. This should not happen",
ex);
}
}
/**
* Initializes the WorkingDaysToDaysConverter for a referenceDate.
*
* @param referenceDate a {@link Instant} that represents the current day of the table
* @return an instance of the WorkingDaysToDaysConverter
* @throws InvalidArgumentException thrown if columnHeaders or referenceDate is null
*/
public static WorkingDaysToDaysConverter initialize(Instant referenceDate)
throws InvalidArgumentException {
if (referenceDate == null) {
throw new InvalidArgumentException("ReferenceDate cannot be used as NULL-Parameter");
}
return new WorkingDaysToDaysConverter(referenceDate);
}
public static void setGermanPublicHolidaysEnabled(boolean germanPublicHolidaysEnabled) {
germanHolidaysEnabled = germanPublicHolidaysEnabled;
}
public static void setCorpusChristiEnabled(boolean corpusChristiEnabled) {
WorkingDaysToDaysConverter.corpusChristiEnabled = corpusChristiEnabled;
}
public static void setCustomHolidays(List<CustomHoliday> holidays) {
customHolidays = new HashSet<>(holidays == null ? Collections.emptyList() : holidays);
}
public long convertWorkingDaysToDays(Instant startTime, long numberOfDays) {
return convertWorkingDaysToDays(startTime, numberOfDays, ZeroDirection.ADD_DAYS);
}
public long convertWorkingDaysToDays(
final Instant startTime, long numberOfDays, ZeroDirection zeroDirection) {
if (startTime == null) {
throw new SystemException(
"Internal Error: convertWorkingDaysToDays was called with a null startTime");
} else if (!startTime.equals(referenceDate)) {
refreshReferenceDate(referenceDate);
}
int direction = calculateDirection(numberOfDays, zeroDirection);
long limit = Math.abs(numberOfDays);
return LongStream.iterate(0, i -> i + direction)
.filter(day -> isWorkingDay(day, startTime))
.skip(limit)
.findFirst()
.orElse(0);
}
public Instant addWorkingDaysToInstant(Instant instant, Duration workingDays) {
long days = convertWorkingDaysToDays(instant, workingDays.toDays(), ZeroDirection.ADD_DAYS);
return instant.plus(Duration.ofDays(days));
}
public Instant subtractWorkingDaysFromInstant(Instant instant, Duration workingDays) {
long days = convertWorkingDaysToDays(instant, -workingDays.toDays(), ZeroDirection.SUB_DAYS);
return instant.plus(Duration.ofDays(days));
}
// counts working days between two dates, exclusive for both margins.
public boolean hasWorkingDaysInBetween(Instant left, Instant right) {
long days = Duration.between(left, right).abs().toDays();
Instant firstInstant = left.isBefore(right) ? left : right;
return LongStream.range(1, days).anyMatch(day -> isWorkingDay(day, firstInstant));
}
public boolean isWorkingDay(long day, Instant referenceDate) {
LocalDateTime dateToCheck =
LocalDateTime.ofInstant(referenceDate, ZoneId.systemDefault()).plusDays(day);
return !isWeekend(dateToCheck) && !isHoliday(dateToCheck.toLocalDate());
}
public boolean isWeekend(LocalDateTime dateToCheck) {
return dateToCheck.getDayOfWeek().equals(DayOfWeek.SATURDAY)
|| dateToCheck.getDayOfWeek().equals(DayOfWeek.SUNDAY);
}
public boolean isHoliday(LocalDate date) {
if (germanHolidaysEnabled && isGermanHoliday(date)) {
return true;
}
// Custom holidays that can be configured in the TaskanaEngineConfiguration
return customHolidays.contains(CustomHoliday.of(date.getDayOfMonth(), date.getMonthValue()));
}
public boolean isGermanHoliday(LocalDate date) {
if (GERMAN_HOLIDAYS.contains(CustomHoliday.of(date.getDayOfMonth(), date.getMonthValue()))) {
return true;
}
// Easter holidays Good Friday, Easter Monday, Ascension Day, Whit Monday.
long diffFromEasterSunday = DAYS.between(easterSunday, date);
Builder builder =
LongStream.builder()
.add(OFFSET_GOOD_FRIDAY)
.add(OFFSET_EASTER_MONDAY)
.add(OFFSET_ASCENSION_DAY)
.add(OFFSET_WHIT_MONDAY);
if (corpusChristiEnabled) {
builder.add(OFFSET_CORPUS_CHRISTI);
}
return builder.build().anyMatch(c -> c == diffFromEasterSunday);
}
/**
* Computes the date of Easter Sunday for a given year.
*
* @param year for which the date of Easter Sunday should be calculated
* @return the date of Easter Sunday for the given year
*/
static LocalDate getEasterSunday(int year) {
// Formula to compute Easter Sunday by Gauss.
int a = year % 19;
int b = year % 4;
int c = year % 7;
int k = year / 100;
int p = (13 + 8 * k) / 25;
int q = k / 4;
int m = (15 - p + k - q) % 30;
int n = (4 + k - q) % 7;
int d = (19 * a + m) % 30;
int e = (2 * b + 4 * c + 6 * d + n) % 7;
if (d == 29 && e == 6) {
return LocalDate.of(year, 3, 15).plusDays((long) d + e);
}
if (d == 28 && e == 6 && (11 * m + 11) % 30 < 19) {
return LocalDate.of(year, 3, 15).plusDays((long) d + e);
}
return LocalDate.of(year, 3, 22).plusDays((long) d + e);
}
void refreshReferenceDate(Instant newReferenceDate) {
int yearOfReferenceDate =
LocalDateTime.ofInstant(referenceDate, ZoneId.systemDefault()).getYear();
int yearOfNewReferenceDate =
LocalDateTime.ofInstant(newReferenceDate, ZoneId.systemDefault()).getYear();
if (yearOfReferenceDate != yearOfNewReferenceDate) {
easterSunday = getEasterSunday(yearOfNewReferenceDate);
}
this.referenceDate = newReferenceDate;
}
private int calculateDirection(long numberOfDays, ZeroDirection zeroDirection) {
if (numberOfDays == 0) {
return zeroDirection.getDirection();
} else {
return numberOfDays >= 0 ? 1 : -1;
}
}
@Override
public String toString() {
return "WorkingDaysToDaysConverter [referenceDate="
+ referenceDate
+ ", easterSunday="
+ easterSunday
+ "]";
}
private enum ZeroDirection {
SUB_DAYS(-1),
ADD_DAYS(1);
private final int direction;
ZeroDirection(int direction) {
this.direction = direction;
}
public int getDirection() {
return direction;
}
}
}

View File

@ -2,8 +2,8 @@ package pro.taskana.monitor.internal.preprocessor;
import java.util.List;
import pro.taskana.common.api.WorkingDaysToDaysConverter;
import pro.taskana.common.api.exceptions.InvalidArgumentException;
import pro.taskana.common.internal.util.WorkingDaysToDaysConverter;
import pro.taskana.monitor.api.reports.header.TimeIntervalColumnHeader;
import pro.taskana.monitor.api.reports.item.AgeQueryItem;
import pro.taskana.monitor.api.reports.item.QueryItemPreprocessor;
@ -19,10 +19,12 @@ public class DaysToWorkingDaysReportPreProcessor<I extends AgeQueryItem>
private WorkingDaysToDaysReportConverter instance;
public DaysToWorkingDaysReportPreProcessor(
List<? extends TimeIntervalColumnHeader> columnHeaders, boolean activate)
List<? extends TimeIntervalColumnHeader> columnHeaders,
WorkingDaysToDaysConverter converter,
boolean activate)
throws InvalidArgumentException {
if (activate) {
instance = WorkingDaysToDaysReportConverter.initialize(columnHeaders);
instance = WorkingDaysToDaysReportConverter.initialize(columnHeaders, converter);
}
}

View File

@ -1,6 +1,7 @@
package pro.taskana.monitor.internal.preprocessor;
import java.time.Instant;
import java.time.temporal.ChronoUnit;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
@ -10,8 +11,8 @@ import java.util.stream.Collectors;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import pro.taskana.common.api.WorkingDaysToDaysConverter;
import pro.taskana.common.api.exceptions.InvalidArgumentException;
import pro.taskana.common.internal.util.WorkingDaysToDaysConverter;
import pro.taskana.monitor.api.reports.header.TimeIntervalColumnHeader;
/**
@ -26,20 +27,22 @@ public class WorkingDaysToDaysReportConverter {
private static final Logger LOGGER =
LoggerFactory.getLogger(WorkingDaysToDaysReportConverter.class);
private final WorkingDaysToDaysConverter daysToWorkingDaysConverter;
private final Map<Integer, Integer> cacheDaysToWorkingDays;
WorkingDaysToDaysReportConverter(
List<? extends TimeIntervalColumnHeader> columnHeaders,
WorkingDaysToDaysConverter daysToWorkingDaysConverter) {
WorkingDaysToDaysConverter daysToWorkingDaysConverter,
Instant referenceDate) {
this.daysToWorkingDaysConverter = daysToWorkingDaysConverter;
cacheDaysToWorkingDays =
generateDaysToWorkingDays(columnHeaders, daysToWorkingDaysConverter.getReferenceDate());
cacheDaysToWorkingDays = generateDaysToWorkingDays(columnHeaders, referenceDate);
}
public static WorkingDaysToDaysReportConverter initialize(
List<? extends TimeIntervalColumnHeader> columnHeaders) throws InvalidArgumentException {
return initialize(columnHeaders, Instant.now());
List<? extends TimeIntervalColumnHeader> columnHeaders,
WorkingDaysToDaysConverter converter) throws InvalidArgumentException {
return initialize(columnHeaders, converter, Instant.now());
}
/**
@ -49,29 +52,31 @@ public class WorkingDaysToDaysReportConverter {
*
* @param columnHeaders a list of {@link TimeIntervalColumnHeader}s that determines the size of
* the table
* @param converter the converter used by taskana to determine if a specific day is a working day.
* @param referenceDate a {@link Instant} that represents the current day of the table
* @return an instance of the WorkingDaysToDaysConverter
* @throws InvalidArgumentException thrown if columnHeaders or referenceDate is null
*/
public static WorkingDaysToDaysReportConverter initialize(
List<? extends TimeIntervalColumnHeader> columnHeaders, Instant referenceDate)
List<? extends TimeIntervalColumnHeader> columnHeaders,
WorkingDaysToDaysConverter converter,
Instant referenceDate)
throws InvalidArgumentException {
if (LOGGER.isDebugEnabled()) {
LOGGER.debug(
"Initialize WorkingDaysToDaysConverter with columnHeaders: {}",
columnHeaders);
LOGGER.debug("Initialize WorkingDaysToDaysConverter with columnHeaders: {}", columnHeaders);
}
if (converter == null) {
throw new InvalidArgumentException("WorkingDaysToDaysConverter can't be null");
}
if (columnHeaders == null) {
throw new InvalidArgumentException(
"TimeIntervalColumnHeaders can´t be used as NULL-Parameter");
throw new InvalidArgumentException("TimeIntervalColumnHeaders can't be null");
}
if (referenceDate == null) {
throw new InvalidArgumentException("ReferenceDate can´t be used as NULL-Parameter");
throw new InvalidArgumentException("ReferenceDate can't be null");
}
WorkingDaysToDaysConverter workingDaysToDaysConverter =
WorkingDaysToDaysConverter.initialize(referenceDate);
return new WorkingDaysToDaysReportConverter(columnHeaders, workingDaysToDaysConverter);
return new WorkingDaysToDaysReportConverter(columnHeaders, converter, referenceDate);
}
public int convertDaysToWorkingDays(int amountOfDays) {
@ -123,8 +128,10 @@ public class WorkingDaysToDaysReportConverter {
int amountOfWorkdays = 0;
while (Math.abs(amountOfWorkdays) < Math.abs(workdayLimit)) {
amountOfDays += direction;
amountOfWorkdays +=
(daysToWorkingDaysConverter.isWorkingDay(amountOfDays, referenceDate)) ? direction : 0;
if (daysToWorkingDaysConverter.isWorkingDay(
referenceDate.plus(amountOfDays, ChronoUnit.DAYS))) {
amountOfWorkdays += direction;
}
daysToWorkingDaysMap.put(amountOfDays, amountOfWorkdays);
}
}

View File

@ -45,7 +45,8 @@ public class CategoryReportBuilderImpl
this.customAttributeFilter);
report.addItems(
monitorQueryItems,
new DaysToWorkingDaysReportPreProcessor<>(this.columnHeaders, this.inWorkingDays));
new DaysToWorkingDaysReportPreProcessor<>(
this.columnHeaders, converter, this.inWorkingDays));
return report;
} finally {
this.taskanaEngine.returnConnection();

View File

@ -48,7 +48,8 @@ public class ClassificationReportBuilderImpl
this.customAttributeFilter);
report.addItems(
monitorQueryItems,
new DaysToWorkingDaysReportPreProcessor<>(this.columnHeaders, this.inWorkingDays));
new DaysToWorkingDaysReportPreProcessor<>(
this.columnHeaders, converter, this.inWorkingDays));
return report;
} finally {
this.taskanaEngine.returnConnection();
@ -76,7 +77,8 @@ public class ClassificationReportBuilderImpl
report.addItems(
detailedMonitorQueryItems,
new DaysToWorkingDaysReportPreProcessor<>(this.columnHeaders, this.inWorkingDays));
new DaysToWorkingDaysReportPreProcessor<>(
this.columnHeaders, converter, this.inWorkingDays));
return report;
} finally {

View File

@ -53,7 +53,8 @@ public class CustomFieldValueReportBuilderImpl
report.addItems(
monitorQueryItems,
new DaysToWorkingDaysReportPreProcessor<>(this.columnHeaders, this.inWorkingDays));
new DaysToWorkingDaysReportPreProcessor<>(
this.columnHeaders, converter, this.inWorkingDays));
return report;
} finally {
this.taskanaEngine.returnConnection();

View File

@ -8,12 +8,11 @@ import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import pro.taskana.TaskanaEngineConfiguration;
import pro.taskana.common.api.TaskanaRole;
import pro.taskana.common.api.WorkingDaysToDaysConverter;
import pro.taskana.common.api.exceptions.InvalidArgumentException;
import pro.taskana.common.api.exceptions.NotAuthorizedException;
import pro.taskana.common.internal.InternalTaskanaEngine;
import pro.taskana.common.internal.util.WorkingDaysToDaysConverter;
import pro.taskana.monitor.api.SelectedItem;
import pro.taskana.monitor.api.reports.ClassificationReport;
import pro.taskana.monitor.api.reports.TimeIntervalReportBuilder;
@ -50,12 +49,13 @@ abstract class TimeIntervalReportBuilderImpl<
protected List<String> classificationIds;
protected List<String> excludedClassificationIds;
protected Map<CustomField, String> customAttributeFilter;
protected WorkingDaysToDaysConverter converter;
TimeIntervalReportBuilderImpl(InternalTaskanaEngine taskanaEngine, MonitorMapper monitorMapper) {
this.taskanaEngine = taskanaEngine;
this.monitorMapper = monitorMapper;
this.columnHeaders = Collections.emptyList();
configureWorkingDaysToDaysConverter();
converter = taskanaEngine.getEngine().getWorkingDaysToDaysConverter();
}
@Override
@ -185,18 +185,10 @@ abstract class TimeIntervalReportBuilderImpl<
protected abstract String determineGroupedBy();
private void configureWorkingDaysToDaysConverter() {
TaskanaEngineConfiguration configuration = taskanaEngine.getEngine().getConfiguration();
WorkingDaysToDaysConverter.setCustomHolidays(configuration.getCustomHolidays());
WorkingDaysToDaysConverter.setGermanPublicHolidaysEnabled(
configuration.isGermanPublicHolidaysEnabled());
WorkingDaysToDaysConverter.setCorpusChristiEnabled(configuration.isCorpusChristiEnabled());
}
private List<SelectedItem> convertWorkingDaysToDays(
List<SelectedItem> selectedItems, List<H> columnHeaders) throws InvalidArgumentException {
WorkingDaysToDaysReportConverter instance =
WorkingDaysToDaysReportConverter.initialize(columnHeaders);
WorkingDaysToDaysReportConverter.initialize(columnHeaders, converter);
for (SelectedItem selectedItem : selectedItems) {
selectedItem.setLowerAgeLimit(
Collections.min(instance.convertWorkingDaysToDays(selectedItem.getLowerAgeLimit())));

View File

@ -46,16 +46,6 @@ public class TimestampReportBuilderImpl
throw new UnsupportedOperationException();
}
@Override
protected TimestampReport.Builder _this() {
return this;
}
@Override
protected String determineGroupedBy() {
throw new UnsupportedOperationException();
}
@Override
public TimestampReport.Builder withTimestamps(List<Timestamp> statuses) {
this.status = new ArrayList<>(statuses);
@ -81,7 +71,9 @@ public class TimestampReportBuilderImpl
.collect(Collectors.toList());
report.addItems(
items, new DaysToWorkingDaysReportPreProcessor<>(this.columnHeaders, this.inWorkingDays));
items,
new DaysToWorkingDaysReportPreProcessor<>(
this.columnHeaders, converter, this.inWorkingDays));
return report;
} finally {
this.taskanaEngine.returnConnection();
@ -89,6 +81,16 @@ public class TimestampReportBuilderImpl
}
}
@Override
protected TimestampReport.Builder _this() {
return this;
}
@Override
protected String determineGroupedBy() {
throw new UnsupportedOperationException();
}
private List<TimestampQueryItem> getTasksCountForStatusGroupedByOrgLevel(Timestamp s) {
return monitorMapper.getTasksCountForStatusGroupedByOrgLevel(
s,

View File

@ -48,7 +48,8 @@ public class WorkbasketReportBuilderImpl
this.combinedClassificationFilter);
report.addItems(
monitorQueryItems,
new DaysToWorkingDaysReportPreProcessor<>(this.columnHeaders, this.inWorkingDays));
new DaysToWorkingDaysReportPreProcessor<>(
this.columnHeaders, converter, this.inWorkingDays));
return report;
} finally {
this.taskanaEngine.returnConnection();
@ -76,7 +77,8 @@ public class WorkbasketReportBuilderImpl
this.combinedClassificationFilter);
report.addItems(
monitorQueryItems,
new DaysToWorkingDaysReportPreProcessor<>(this.columnHeaders, this.inWorkingDays));
new DaysToWorkingDaysReportPreProcessor<>(
this.columnHeaders, converter, this.inWorkingDays));
return report;
} finally {
this.taskanaEngine.returnConnection();

View File

@ -17,10 +17,10 @@ import org.slf4j.LoggerFactory;
import pro.taskana.classification.api.models.ClassificationSummary;
import pro.taskana.common.api.BulkOperationResults;
import pro.taskana.common.api.WorkingDaysToDaysConverter;
import pro.taskana.common.api.exceptions.InvalidArgumentException;
import pro.taskana.common.api.exceptions.TaskanaException;
import pro.taskana.common.internal.InternalTaskanaEngine;
import pro.taskana.common.internal.util.WorkingDaysToDaysConverter;
import pro.taskana.task.api.exceptions.UpdateFailedException;
import pro.taskana.task.api.models.Attachment;
import pro.taskana.task.api.models.AttachmentSummary;
@ -46,11 +46,7 @@ class ServiceLevelHandler {
this.taskanaEngine = taskanaEngine;
this.taskMapper = taskMapper;
this.attachmentMapper = attachmentMapper;
WorkingDaysToDaysConverter.setGermanPublicHolidaysEnabled(
taskanaEngine.getEngine().getConfiguration().isGermanPublicHolidaysEnabled());
WorkingDaysToDaysConverter.setCorpusChristiEnabled(
taskanaEngine.getEngine().getConfiguration().isCorpusChristiEnabled());
this.converter = WorkingDaysToDaysConverter.initialize();
converter = taskanaEngine.getEngine().getWorkingDaysToDaysConverter();
}
// use the same algorithm as setPlannedPropertyOfTasksImpl to refresh
@ -91,9 +87,7 @@ class ServiceLevelHandler {
List<ClassificationSummary> allInvolvedClassifications =
findAllClassificationsReferencedByTasksAndAttachments(tasks, attachments);
if (LOGGER.isDebugEnabled()) {
LOGGER.debug(
"found involved classifications {}.",
allInvolvedClassifications);
LOGGER.debug("found involved classifications {}.", allInvolvedClassifications);
}
List<ClassificationWithServiceLevelResolved> allInvolvedClassificationsWithDuration =
resolveDurationsInClassifications(allInvolvedClassifications);
@ -317,7 +311,7 @@ class ServiceLevelHandler {
if (task.getPlanned() != null
&& !task.getPlanned().equals(calcPlanned)
// manual entered planned date is a different working day than computed value
&& (converter.isWorkingDay(0, task.getPlanned())
&& (converter.isWorkingDay(task.getPlanned())
|| converter.hasWorkingDaysInBetween(task.getPlanned(), calcPlanned))) {
throw new InvalidArgumentException(
String.format(

View File

@ -20,8 +20,8 @@ import pro.taskana.classification.api.exceptions.ClassificationNotFoundException
import pro.taskana.common.api.TaskanaEngine;
import pro.taskana.common.api.TaskanaEngine.ConnectionManagementMode;
import pro.taskana.common.api.TimeInterval;
import pro.taskana.common.api.WorkingDaysToDaysConverter;
import pro.taskana.common.internal.TaskanaEngineTestConfiguration;
import pro.taskana.common.internal.util.WorkingDaysToDaysConverter;
import pro.taskana.sampledata.SampleDataGenerator;
import pro.taskana.task.api.models.Attachment;
import pro.taskana.task.api.models.ObjectReference;
@ -33,11 +33,6 @@ public abstract class AbstractAccTest {
protected static TaskanaEngine taskanaEngine;
protected static WorkingDaysToDaysConverter converter;
public AbstractAccTest() {
WorkingDaysToDaysConverter.setGermanPublicHolidaysEnabled(true);
converter = WorkingDaysToDaysConverter.initialize();
}
@BeforeAll
public static void setupTest() throws Exception {
resetDb(false);
@ -55,6 +50,7 @@ public abstract class AbstractAccTest {
taskanaEngineConfiguration.setGermanPublicHolidaysEnabled(true);
taskanaEngine = taskanaEngineConfiguration.buildTaskanaEngine();
taskanaEngine.setConnectionManagementMode(ConnectionManagementMode.AUTOCOMMIT);
converter = taskanaEngine.getWorkingDaysToDaysConverter();
sampleDataGenerator.clearDb();
sampleDataGenerator.generateTestData();
}

View File

@ -19,13 +19,13 @@ import org.junit.jupiter.api.extension.ExtendWith;
import pro.taskana.classification.api.ClassificationService;
import pro.taskana.classification.api.exceptions.ClassificationNotFoundException;
import pro.taskana.classification.api.models.Classification;
import pro.taskana.common.api.WorkingDaysToDaysConverter;
import pro.taskana.common.api.exceptions.ConcurrencyException;
import pro.taskana.common.api.exceptions.InvalidArgumentException;
import pro.taskana.common.api.exceptions.NotAuthorizedException;
import pro.taskana.common.internal.jobs.JobRunner;
import pro.taskana.common.internal.security.JaasExtension;
import pro.taskana.common.internal.security.WithAccessId;
import pro.taskana.common.internal.util.WorkingDaysToDaysConverter;
import pro.taskana.task.api.TaskService;
import pro.taskana.task.api.exceptions.TaskNotFoundException;
import pro.taskana.task.api.models.Task;
@ -225,7 +225,6 @@ class UpdateClassificationAccTest extends AbstractAccTest {
// TODO - resume old behaviour after attachment query is possible.
TaskService taskService = taskanaEngine.getTaskService();
WorkingDaysToDaysConverter converter = WorkingDaysToDaysConverter.initialize(Instant.now());
List<String> tasksWithP1D =
new ArrayList<>(
@ -334,8 +333,6 @@ class UpdateClassificationAccTest extends AbstractAccTest {
assertThat(modifiedBefore.isAfter(updatedClassification.getModified())).isFalse();
// TODO - resume old behaviour after attachment query is possible.
TaskService taskService = taskanaEngine.getTaskService();
WorkingDaysToDaysConverter.setGermanPublicHolidaysEnabled(true);
WorkingDaysToDaysConverter converter = WorkingDaysToDaysConverter.initialize(Instant.now());
List<String> tasksWithPrio99 =
new ArrayList<>(
@ -473,8 +470,6 @@ class UpdateClassificationAccTest extends AbstractAccTest {
assertThat(modifiedBefore.isAfter(updatedClassification.getModified())).isFalse();
// TODO - resume old behaviour after attachment query is possible.
TaskService taskService = taskanaEngine.getTaskService();
WorkingDaysToDaysConverter.setGermanPublicHolidaysEnabled(true);
WorkingDaysToDaysConverter converter = WorkingDaysToDaysConverter.initialize(Instant.now());
List<String> tasksWithPD12 =
new ArrayList<>(
Arrays.asList(
@ -563,15 +558,10 @@ class UpdateClassificationAccTest extends AbstractAccTest {
assertThat(task.getModified())
.describedAs("Task " + task.getId() + " has not been refreshed.")
.isAfter(before);
long calendarDays = converter.convertWorkingDaysToDays(task.getPlanned(), serviceLevel);
Instant expDue =
converter.addWorkingDaysToInstant(task.getPlanned(), Duration.ofDays(serviceLevel));
String msg =
String.format(
"Task: %s and Due Date: %s do not match planned %s. Calendar days : %s.",
taskId, task.getDue(), task.getPlanned(), calendarDays);
assertThat(task.getDue())
.describedAs(msg)
.isEqualTo(task.getPlanned().plus(Duration.ofDays(calendarDays)));
assertThat(task.getDue()).isEqualTo(expDue);
assertThat(task.getPriority()).isEqualTo(priority);
}
}

View File

@ -25,7 +25,6 @@ import pro.taskana.common.api.exceptions.NotAuthorizedException;
import pro.taskana.common.internal.JobServiceImpl;
import pro.taskana.common.internal.security.JaasExtension;
import pro.taskana.common.internal.security.WithAccessId;
import pro.taskana.common.internal.util.WorkingDaysToDaysConverter;
import pro.taskana.task.api.TaskService;
import pro.taskana.task.api.exceptions.AttachmentPersistenceException;
import pro.taskana.task.api.exceptions.InvalidStateException;
@ -58,8 +57,6 @@ public class UpdateObjectsUseUtcTimeStampsAccTest extends AbstractAccTest {
task.setPlanned(now.plus(Duration.ofHours(17)));
WorkingDaysToDaysConverter.setGermanPublicHolidaysEnabled(true);
WorkingDaysToDaysConverter converter = WorkingDaysToDaysConverter.initialize(Instant.now());
// associated Classification has ServiceLevel 'P1D'
task.setDue(converter.addWorkingDaysToInstant(task.getPlanned(), Duration.ofDays(1)));

View File

@ -437,10 +437,10 @@ class CreateTaskAccTest extends AbstractAccTest {
assertThat(readTask.getPriority()).isEqualTo(99);
long calendarDays = converter.convertWorkingDaysToDays(readTask.getPlanned(), 1);
Instant expDue =
converter.addWorkingDaysToInstant(readTask.getPlanned(), Duration.ofDays(1));
assertThat(readTask.getPlanned().plus(Duration.ofDays(calendarDays)))
.isEqualTo(readTask.getDue());
assertThat(readTask.getDue()).isEqualTo(expDue);
}
@WithAccessId(user = "user-1-1", groups = "group-1")

View File

@ -11,6 +11,7 @@ import java.time.Instant;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map.Entry;
import org.assertj.core.api.ThrowableAssert.ThrowingCallable;
@ -22,13 +23,13 @@ import pro.taskana.classification.api.ClassificationService;
import pro.taskana.classification.api.exceptions.ClassificationNotFoundException;
import pro.taskana.classification.api.models.Classification;
import pro.taskana.common.api.BulkOperationResults;
import pro.taskana.common.api.WorkingDaysToDaysConverter;
import pro.taskana.common.api.exceptions.ConcurrencyException;
import pro.taskana.common.api.exceptions.InvalidArgumentException;
import pro.taskana.common.api.exceptions.NotAuthorizedException;
import pro.taskana.common.api.exceptions.TaskanaException;
import pro.taskana.common.internal.security.JaasExtension;
import pro.taskana.common.internal.security.WithAccessId;
import pro.taskana.common.internal.util.WorkingDaysToDaysConverter;
import pro.taskana.task.api.TaskService;
import pro.taskana.task.api.exceptions.AttachmentPersistenceException;
import pro.taskana.task.api.exceptions.InvalidStateException;
@ -47,10 +48,9 @@ public class ServiceLevelPriorityAccTest extends AbstractAccTest {
private final WorkingDaysToDaysConverter converter;
ServiceLevelPriorityAccTest() {
WorkingDaysToDaysConverter.setGermanPublicHolidaysEnabled(true);
taskService = taskanaEngine.getTaskService();
classificationService = taskanaEngine.getClassificationService();
converter = WorkingDaysToDaysConverter.initialize();
converter = taskanaEngine.getWorkingDaysToDaysConverter();
}
/* CREATE TASK */
@ -80,14 +80,9 @@ public class ServiceLevelPriorityAccTest extends AbstractAccTest {
assertThat(readTask).isNotNull();
assertThat(readTask.getDue()).isEqualTo(due);
long calendarDaysToSubtract = converter.convertWorkingDaysToDays(due, -serviceLevelDays);
assertThat(calendarDaysToSubtract < 0).isTrue();
assertThat(calendarDaysToSubtract <= serviceLevelDays).isTrue();
Instant expectedPlanned =
moveBackToWorkingDay(due.plus(Duration.ofDays(calendarDaysToSubtract)));
assertThat(expectedPlanned).isEqualTo(readTask.getPlanned());
converter.subtractWorkingDaysFromInstant(due, Duration.ofDays(serviceLevelDays));
assertThat(readTask.getPlanned()).isEqualTo(expectedPlanned);
}
@WithAccessId(user = "user-1-1", groups = "group-1")
@ -115,11 +110,10 @@ public class ServiceLevelPriorityAccTest extends AbstractAccTest {
assertThat(readTask).isNotNull();
assertThat(readTask.getPlanned()).isEqualTo(planned);
long calendarDays = converter.convertWorkingDaysToDays(readTask.getPlanned(), serviceLevelDays);
Instant expectedDue =
moveForwardToWorkingDay(readTask.getPlanned().plus(Duration.ofDays(calendarDays)));
assertThat(expectedDue).isEqualTo(readTask.getDue());
converter.addWorkingDaysToInstant(readTask.getPlanned(), Duration.ofDays(serviceLevelDays));
assertThat(readTask.getDue()).isEqualTo(expectedDue);
}
@WithAccessId(user = "user-1-1", groups = "group-1")
@ -138,15 +132,11 @@ public class ServiceLevelPriorityAccTest extends AbstractAccTest {
newTask.setOwner("user-1-1");
// due date according to service level
long daysToDue = converter.convertWorkingDaysToDays(newTask.getPlanned(), duration);
Instant expectedDue =
moveForwardToWorkingDay(newTask.getPlanned().plus(Duration.ofDays(daysToDue)));
converter.addWorkingDaysToInstant(newTask.getPlanned(), Duration.ofDays(duration));
newTask.setDue(expectedDue);
ThrowingCallable call =
() -> {
taskService.createTask(newTask);
};
ThrowingCallable call = () -> taskService.createTask(newTask);
assertThatCode(call).doesNotThrowAnyException();
}
@ -163,10 +153,7 @@ public class ServiceLevelPriorityAccTest extends AbstractAccTest {
newTask.setPlanned(planned);
newTask.setDue(planned); // due date not according to service level
ThrowingCallable call =
() -> {
taskService.createTask(newTask);
};
ThrowingCallable call = () -> taskService.createTask(newTask);
assertThatThrownBy(call).isInstanceOf(InvalidArgumentException.class);
}
@ -275,10 +262,7 @@ public class ServiceLevelPriorityAccTest extends AbstractAccTest {
@WithAccessId(user = "user-1-1", groups = "group-2")
@Test
void should_SetPlanned_When_RequestContainsTasksWithAttachments()
throws NotAuthorizedException, TaskNotFoundException, ClassificationNotFoundException,
InvalidArgumentException, InvalidStateException, ConcurrencyException,
AttachmentPersistenceException {
void should_SetPlanned_When_RequestContainsTasksWithAttachments() throws Exception {
// This test works with the following tasks, attachments and classifications
//
@ -335,7 +319,7 @@ public class ServiceLevelPriorityAccTest extends AbstractAccTest {
assertThat(results.containsErrors()).isFalse();
assertThat(dueBulk0).isEqualTo(due0);
// assertThat(dueBulk1).isEqualTo(due1); in this method, a bug in the code is visible
assertThat(dueBulk1).isEqualTo(due1);
assertThat(dueBulk2).isEqualTo(due2);
}
@ -424,12 +408,11 @@ public class ServiceLevelPriorityAccTest extends AbstractAccTest {
Instant planned = getInstant("2020-05-03T07:00:00");
// test bulk operation setPlanned...
BulkOperationResults<String, TaskanaException> results =
taskService.setPlannedPropertyOfTasks(planned, Arrays.asList(taskId));
taskService.setPlannedPropertyOfTasks(planned, Collections.singletonList(taskId));
Task task = taskService.getTask(taskId);
assertThat(results.containsErrors()).isFalse();
WorkingDaysToDaysConverter converter = WorkingDaysToDaysConverter.initialize();
long days = converter.convertWorkingDaysToDays(task.getPlanned(), 1);
assertThat(task.getDue()).isEqualTo(planned.plus(Duration.ofDays(days)));
Instant expectedDue = converter.addWorkingDaysToInstant(task.getPlanned(), Duration.ofDays(1));
assertThat(task.getDue()).isEqualTo(expectedDue);
}
@WithAccessId(user = "admin", groups = "group-2")
@ -439,13 +422,12 @@ public class ServiceLevelPriorityAccTest extends AbstractAccTest {
ConcurrencyException, InvalidStateException, ClassificationNotFoundException,
AttachmentPersistenceException {
String taskId = "TKI:000000000000000000000000000000000002";
WorkingDaysToDaysConverter converter = WorkingDaysToDaysConverter.initialize();
Task task = taskService.getTask(taskId);
// test update of planned date via updateTask()
task.setPlanned(task.getPlanned().plus(Duration.ofDays(3)));
task = taskService.updateTask(task);
long days = converter.convertWorkingDaysToDays(task.getPlanned(), 1);
assertThat(task.getDue()).isEqualTo(task.getPlanned().plus(Duration.ofDays(days)));
Instant expectedDue = converter.addWorkingDaysToInstant(task.getPlanned(), Duration.ofDays(1));
assertThat(task.getDue()).isEqualTo(expectedDue);
}
@WithAccessId(user = "admin", groups = "group-2")
@ -466,37 +448,33 @@ public class ServiceLevelPriorityAccTest extends AbstractAccTest {
@WithAccessId(user = "admin", groups = "group-2")
@Test
void should_SetDue_When_OnlyPlannedWasChanged()
throws NotAuthorizedException, TaskNotFoundException, InvalidArgumentException,
ConcurrencyException, InvalidStateException, ClassificationNotFoundException,
AttachmentPersistenceException {
void should_SetDue_When_OnlyPlannedWasChanged() throws Exception {
String taskId = "TKI:000000000000000000000000000000000002";
Instant planned = getInstant("2020-05-03T07:00:00");
Task task = taskService.getTask(taskId);
task.setDue(planned.plus(Duration.ofDays(3)));
WorkingDaysToDaysConverter converter = WorkingDaysToDaysConverter.initialize();
long days = converter.convertWorkingDaysToDays(task.getDue(), -1);
task.setPlanned(task.getDue().plus(Duration.ofDays(-1)));
task.setPlanned(planned);
task = taskService.updateTask(task);
days = converter.convertWorkingDaysToDays(task.getDue(), -1);
assertThat(task.getPlanned()).isEqualTo(task.getDue().plus(Duration.ofDays(days)));
String serviceLevel = task.getClassificationSummary().getServiceLevel();
Instant expDue = converter.addWorkingDaysToInstant(task.getPlanned(), Duration.parse(serviceLevel));
assertThat(task.getPlanned()).isEqualTo(planned);
assertThat(task.getDue()).isEqualTo(expDue);
}
@WithAccessId(user = "admin", groups = "group-2")
@Test
void should_SetPlanned_When_DueIsChangedAndPlannedIsNulled()
throws NotAuthorizedException, TaskNotFoundException, InvalidArgumentException,
ConcurrencyException, InvalidStateException, ClassificationNotFoundException,
AttachmentPersistenceException {
void should_SetPlanned_When_DueIsChangedAndPlannedIsNulled() throws Exception {
String taskId = "TKI:000000000000000000000000000000000002";
Instant planned = getInstant("2020-05-03T07:00:00");
Instant due = getInstant("2020-05-06T07:00:00");
Task task = taskService.getTask(taskId);
task.setDue(planned.plus(Duration.ofDays(3)));
task.setDue(due);
task.setPlanned(null);
task = taskService.updateTask(task);
WorkingDaysToDaysConverter converter = WorkingDaysToDaysConverter.initialize();
long days = converter.convertWorkingDaysToDays(task.getDue(), -1);
assertThat(task.getPlanned()).isEqualTo(task.getDue().plus(Duration.ofDays(days)));
String serviceLevel = task.getClassificationSummary().getServiceLevel();
Instant expPlanned =
converter.subtractWorkingDaysFromInstant(task.getDue(), Duration.parse(serviceLevel));
assertThat(task.getPlanned()).isEqualTo(expPlanned);
assertThat(task.getDue()).isEqualTo(due);
}
@WithAccessId(user = "admin", groups = "group-2")
@ -511,20 +489,19 @@ public class ServiceLevelPriorityAccTest extends AbstractAccTest {
task.setPlanned(null);
task = taskService.updateTask(task);
WorkingDaysToDaysConverter converter = WorkingDaysToDaysConverter.initialize();
long days = converter.convertWorkingDaysToDays(task.getPlanned(), 1);
assertThat(task.getDue()).isEqualTo(task.getPlanned().plus(Duration.ofDays(days)));
Instant expectedDue = converter.addWorkingDaysToInstant(task.getPlanned(), Duration.ofDays(1));
assertThat(task.getDue()).isEqualTo(expectedDue);
task.setDue(null);
task = taskService.updateTask(task);
days = converter.convertWorkingDaysToDays(task.getPlanned(), 1);
assertThat(task.getDue()).isEqualTo(task.getPlanned().plus(Duration.ofDays(days)));
expectedDue = converter.addWorkingDaysToInstant(task.getPlanned(), Duration.ofDays(1));
assertThat(task.getDue()).isEqualTo(expectedDue);
task.setPlanned(planned.plus(Duration.ofDays(13))); // Saturday
task.setDue(null);
task = taskService.updateTask(task);
days = converter.convertWorkingDaysToDays(task.getPlanned(), 1);
assertThat(task.getDue()).isEqualTo(task.getPlanned().plus(Duration.ofDays(days)));
expectedDue = converter.addWorkingDaysToInstant(task.getPlanned(), Duration.ofDays(1));
assertThat(task.getDue()).isEqualTo(expectedDue);
task.setDue(planned.plus(Duration.ofDays(13))); // Saturday
task.setPlanned(null);

View File

@ -2,13 +2,12 @@ package acceptance.task;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.assertj.core.api.Assertions.fail;
import acceptance.AbstractAccTest;
import java.time.Duration;
import java.time.Instant;
import java.util.ArrayList;
import java.util.List;
import org.assertj.core.api.Condition;
import org.assertj.core.api.ThrowableAssert.ThrowingCallable;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
@ -23,7 +22,6 @@ import pro.taskana.common.api.exceptions.NotAuthorizedException;
import pro.taskana.common.internal.security.CurrentUserContext;
import pro.taskana.common.internal.security.JaasExtension;
import pro.taskana.common.internal.security.WithAccessId;
import pro.taskana.common.internal.util.WorkingDaysToDaysConverter;
import pro.taskana.task.api.TaskService;
import pro.taskana.task.api.exceptions.AttachmentPersistenceException;
import pro.taskana.task.api.exceptions.InvalidStateException;
@ -169,9 +167,8 @@ class UpdateTaskAttachmentsAccTest extends AbstractAccTest {
assertThat(task.getAttachments().get(0).getChannel()).isEqualTo(newChannel);
assertThat(task.getPriority()).isEqualTo(999);
WorkingDaysToDaysConverter converter = WorkingDaysToDaysConverter.initialize(Instant.now());
long calendarDays = converter.convertWorkingDaysToDays(task.getDue(), 1);
assertThat(task.getPlanned().plus(Duration.ofDays(calendarDays))).isEqualTo(task.getDue());
Instant expDue = converter.addWorkingDaysToInstant(task.getPlanned(), Duration.ofDays(1));
assertThat(task.getDue()).isEqualTo(expDue);
}
@WithAccessId(user = "user-1-1", groups = "group-1")
@ -308,18 +305,14 @@ class UpdateTaskAttachmentsAccTest extends AbstractAccTest {
assertThat(task.getAttachments()).hasSize(attachmentCount);
assertThat(task.getAttachments().get(0).getChannel()).isEqualTo(newChannel);
assertThat(task.getPriority()).isEqualTo(999);
WorkingDaysToDaysConverter converter = WorkingDaysToDaysConverter.initialize(Instant.now());
long calendarDays = converter.convertWorkingDaysToDays(task.getDue(), 1);
Instant expDue = converter.addWorkingDaysToInstant(task.getPlanned(), Duration.ofDays(1));
assertThat(task.getPlanned().plus(Duration.ofDays(calendarDays))).isEqualTo(task.getDue());
assertThat(task.getDue()).isEqualTo(expDue);
}
@WithAccessId(user = "user-1-1", groups = "group-1")
@Test
void modifyExistingAttachment()
throws TaskNotFoundException, ClassificationNotFoundException, NotAuthorizedException,
InvalidArgumentException, ConcurrencyException, AttachmentPersistenceException,
InvalidStateException {
void modifyExistingAttachment() throws Exception {
// setup test
assertThat(task.getAttachments()).isEmpty();
task.addAttachment(attachment);
@ -339,33 +332,19 @@ class UpdateTaskAttachmentsAccTest extends AbstractAccTest {
task.addAttachment(attachment2);
task = taskService.updateTask(task);
task = taskService.getTask(task.getId());
assertThat(task.getPriority()).isEqualTo(101);
WorkingDaysToDaysConverter converter = WorkingDaysToDaysConverter.initialize(Instant.now());
long calendarDays = converter.convertWorkingDaysToDays(task.getDue(), 1);
assertThat(task.getPlanned().plus(Duration.ofDays(calendarDays))).isEqualTo(task.getDue());
assertThat(task.getAttachments()).hasSize(2);
List<Attachment> attachments = task.getAttachments();
boolean rohrpostFound = false;
boolean emailFound = false;
for (Attachment att : attachments) {
String channel = att.getChannel();
int custAttSize = att.getCustomAttributes().size();
if ("ROHRPOST".equals(channel)) {
rohrpostFound = true;
assertThat(task.getModified()).isEqualTo(att.getModified());
} else if ("E-MAIL".equals(channel)) {
emailFound = true;
} else {
fail("unexpected attachment detected " + att);
}
assertThat(
("ROHRPOST".equals(channel) && custAttSize == 4)
|| ("E-MAIL".equals(channel) && custAttSize == 3))
.isTrue();
}
assertThat(rohrpostFound && emailFound).isTrue();
Instant expDue = converter.addWorkingDaysToInstant(task.getPlanned(), Duration.ofDays(1));
assertThat(task.getDue()).isEqualTo(expDue);
assertThat(task.getAttachments()).hasSize(2)
.areExactly(1,
new Condition<>(
e -> "E-MAIL".equals(e.getChannel()) && e.getCustomAttributes().size() == 3,
"E-MAIL with 3 custom attributes"))
.areExactly(1,
new Condition<>(
e -> "ROHRPOST".equals(e.getChannel()) && e.getCustomAttributes().size() == 4,
"ROHRPOST with 4 custom attributes"));
ClassificationSummary newClassificationSummary =
taskanaEngine
@ -385,30 +364,18 @@ class UpdateTaskAttachmentsAccTest extends AbstractAccTest {
task = taskService.getTask(task.getId());
assertThat(task.getPriority()).isEqualTo(99);
calendarDays = converter.convertWorkingDaysToDays(task.getDue(), 16);
assertThat(task.getPlanned().plus(Duration.ofDays(calendarDays))).isEqualTo(task.getDue());
rohrpostFound = false;
boolean faxFound = false;
for (Attachment att : task.getAttachments()) {
String channel = att.getChannel();
int custAttSize = att.getCustomAttributes().size();
if ("FAX".equals(channel)) {
faxFound = true;
} else if ("ROHRPOST".equals(channel)) {
rohrpostFound = true;
} else {
fail("unexpected attachment detected " + att);
}
assertThat(
("ROHRPOST".equals(channel) && custAttSize == 4)
|| ("FAX".equals(channel) && custAttSize == 3))
.isTrue();
}
assertThat(faxFound && rohrpostFound).isTrue();
expDue = converter.addWorkingDaysToInstant(task.getPlanned(), Duration.ofDays(16));
assertThat(task.getDue()).isEqualTo(expDue);
assertThat(task.getAttachments())
.hasSize(2)
.areExactly(1,
new Condition<>(
e -> "FAX".equals(e.getChannel()) && e.getCustomAttributes().size() == 3,
"FAX with 3 custom attributes"))
.areExactly(1,
new Condition<>(
e -> "ROHRPOST".equals(e.getChannel()) && e.getCustomAttributes().size() == 4,
"ROHRPOST with 4 custom attributes"));
}
@WithAccessId(user = "user-1-1", groups = "group-1")
@ -528,19 +495,14 @@ class UpdateTaskAttachmentsAccTest extends AbstractAccTest {
assertThat(readTask.getPriority()).isEqualTo(99);
WorkingDaysToDaysConverter converter = WorkingDaysToDaysConverter.initialize(Instant.now());
long calendarDays = converter.convertWorkingDaysToDays(readTask.getPlanned(), 1);
Instant expDue = converter.addWorkingDaysToInstant(readTask.getPlanned(), Duration.ofDays(1));
assertThat(readTask.getPlanned().plus(Duration.ofDays(calendarDays)))
.isEqualTo(readTask.getDue());
assertThat(readTask.getDue()).isEqualTo(expDue);
}
@WithAccessId(user = "user-1-1", groups = "group-1")
@Test
void testAddCustomAttributeToAttachment()
throws TaskNotFoundException, ClassificationNotFoundException, NotAuthorizedException,
InvalidArgumentException, ConcurrencyException, AttachmentPersistenceException,
InvalidStateException {
void testAddCustomAttributeToAttachment() throws Exception {
TaskService taskService = taskanaEngine.getTaskService();
task =

View File

@ -0,0 +1,214 @@
package pro.taskana.common.api;
import static org.assertj.core.api.Assertions.assertThat;
import java.time.Duration;
import java.time.Instant;
import java.time.LocalDate;
import java.time.temporal.ChronoUnit;
import java.util.Arrays;
import java.util.stream.Stream;
import org.junit.jupiter.api.DynamicContainer;
import org.junit.jupiter.api.DynamicNode;
import org.junit.jupiter.api.DynamicTest;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestFactory;
import pro.taskana.common.api.WorkingDaysToDaysConverter.EasterCalculator;
/** Test for the WorkingDaysToDaysConverter. */
class WorkingDaysToDaysConverterTest {
private final WorkingDaysToDaysConverter converter;
WorkingDaysToDaysConverterTest() {
CustomHoliday dayOfReformation = CustomHoliday.of(31, 10);
CustomHoliday allSaintsDays = CustomHoliday.of(1, 11);
converter =
new WorkingDaysToDaysConverter(true, false, Arrays.asList(dayOfReformation, allSaintsDays));
}
@TestFactory
Stream<DynamicTest> should_NotDetectCorpusChristiAsHoliday_When_CorpusChristiIsDisabled() {
DynamicTest year1980 =
DynamicTest.dynamicTest(
"year 1980",
() -> assertThat(converter.isGermanHoliday(LocalDate.parse("1980-06-05"))).isFalse());
DynamicTest year2020 =
DynamicTest.dynamicTest(
"year 2020",
() -> assertThat(converter.isGermanHoliday(LocalDate.parse("2020-06-11"))).isFalse());
return Stream.of(year1980, year2020);
}
@TestFactory
Stream<DynamicNode> should_DetectCorpusChristiAsHoliday_When_CorpusChristiIsEnabled() {
WorkingDaysToDaysConverter converter = new WorkingDaysToDaysConverter(true, true);
DynamicTest year1980 =
DynamicTest.dynamicTest(
"year 1980",
() -> assertThat(converter.isGermanHoliday(LocalDate.parse("1980-06-05"))).isTrue());
DynamicTest year2020 =
DynamicTest.dynamicTest(
"year 2020",
() -> assertThat(converter.isGermanHoliday(LocalDate.parse("2020-06-11"))).isTrue());
return Stream.of(year1980, year2020);
}
@TestFactory
Stream<DynamicNode> testHasWorkingInBetween() {
Instant thursday = Instant.parse("2020-04-30T07:12:00.000Z");
Instant friday = Instant.parse("2020-05-01T07:12:00.000Z"); // german holiday
Instant saturday = Instant.parse("2020-05-02T07:12:00.000Z");
Instant sunday = Instant.parse("2020-05-03T07:12:00.000Z");
Instant monday = Instant.parse("2020-05-04T07:12:00.000Z");
Instant tuesday = Instant.parse("2020-05-05T07:12:00.000Z");
DynamicContainer noWorkingDaysInBetween =
DynamicContainer.dynamicContainer(
"no working days in between",
Stream.of(
DynamicTest.dynamicTest(
"tuesday <-> tuesday",
() ->
assertThat(converter.hasWorkingDaysInBetween(tuesday, tuesday)).isFalse()),
DynamicTest.dynamicTest(
"thursday <-> saturday (friday is holiday)",
() ->
assertThat(converter.hasWorkingDaysInBetween(thursday, saturday))
.isFalse()),
DynamicTest.dynamicTest(
"friday <-> friday",
() -> assertThat(converter.hasWorkingDaysInBetween(friday, friday)).isFalse()),
DynamicTest.dynamicTest(
"friday <-> monday",
() -> assertThat(converter.hasWorkingDaysInBetween(friday, monday)).isFalse()),
DynamicTest.dynamicTest(
"saturday <-> monday",
() ->
assertThat(converter.hasWorkingDaysInBetween(saturday, monday)).isFalse()),
DynamicTest.dynamicTest(
"sunday <-> monday",
() -> assertThat(converter.hasWorkingDaysInBetween(sunday, monday)).isFalse()),
DynamicTest.dynamicTest(
"monday <-> monday",
() -> assertThat(converter.hasWorkingDaysInBetween(sunday, monday)).isFalse()),
DynamicTest.dynamicTest(
"monday <-> sunday",
() -> assertThat(converter.hasWorkingDaysInBetween(monday, sunday)).isFalse()),
DynamicTest.dynamicTest(
"monday <-> friday",
() ->
assertThat(converter.hasWorkingDaysInBetween(monday, friday)).isFalse())));
DynamicContainer hasWorkingDaysInBetween =
DynamicContainer.dynamicContainer(
"has working days in between",
Stream.of(
DynamicTest.dynamicTest(
"friday <-> tuesday",
() -> assertThat(converter.hasWorkingDaysInBetween(friday, tuesday)).isTrue()),
DynamicTest.dynamicTest(
"sunday <-> tuesday",
() ->
assertThat(converter.hasWorkingDaysInBetween(sunday, tuesday)).isTrue())));
return Stream.of(noWorkingDaysInBetween, hasWorkingDaysInBetween);
}
@Test
void testConvertWorkingDaysToDaysForTasks() {
Instant thursday0201 = Instant.parse("2018-02-01T07:00:00.000Z");
Instant days =
converter.subtractWorkingDaysFromInstant(
thursday0201, Duration.ofDays(7)); // = tuesday (sat + sun)
assertThat(days).isEqualTo(thursday0201.minus(9, ChronoUnit.DAYS));
days =
converter.subtractWorkingDaysFromInstant(
thursday0201, Duration.ofDays(6)); // = wednesday (sat + sun)
assertThat(days).isEqualTo(thursday0201.minus(8, ChronoUnit.DAYS));
days =
converter.subtractWorkingDaysFromInstant(
thursday0201, Duration.ofDays(5)); // = thursday (sat + sun)
assertThat(days).isEqualTo(thursday0201.minus(7, ChronoUnit.DAYS));
days = converter.subtractWorkingDaysFromInstant(thursday0201, Duration.ofDays(4)); // = friday
assertThat(days).isEqualTo(thursday0201.minus(6, ChronoUnit.DAYS));
days = converter.subtractWorkingDaysFromInstant(thursday0201, Duration.ofDays(3)); // monday
assertThat(days).isEqualTo(thursday0201.minus(3, ChronoUnit.DAYS));
days = converter.subtractWorkingDaysFromInstant(thursday0201, Duration.ofDays(2)); // tuesday
assertThat(days).isEqualTo(thursday0201.minus(2, ChronoUnit.DAYS));
days = converter.subtractWorkingDaysFromInstant(thursday0201, Duration.ofDays(1)); // wednesday
assertThat(days).isEqualTo(thursday0201.minus(1, ChronoUnit.DAYS));
days = converter.addWorkingDaysToInstant(thursday0201, Duration.ofDays(0)); // = thursday
assertThat(days).isEqualTo(thursday0201.plus(0, ChronoUnit.DAYS));
days = converter.addWorkingDaysToInstant(thursday0201, Duration.ofDays(1)); // fri
assertThat(days).isEqualTo(thursday0201.plus(1, ChronoUnit.DAYS));
days = converter.addWorkingDaysToInstant(thursday0201, Duration.ofDays(2)); // mon
assertThat(days).isEqualTo(thursday0201.plus(4, ChronoUnit.DAYS));
days = converter.addWorkingDaysToInstant(thursday0201, Duration.ofDays(3)); // tues
assertThat(days).isEqualTo(thursday0201.plus(5, ChronoUnit.DAYS));
days = converter.addWorkingDaysToInstant(thursday0201, Duration.ofDays(4)); // we
assertThat(days).isEqualTo(thursday0201.plus(6, ChronoUnit.DAYS));
days = converter.addWorkingDaysToInstant(thursday0201, Duration.ofDays(5)); // thurs
assertThat(days).isEqualTo(thursday0201.plus(7, ChronoUnit.DAYS));
days = converter.addWorkingDaysToInstant(thursday0201, Duration.ofDays(6)); // fri
assertThat(days).isEqualTo(thursday0201.plus(8, ChronoUnit.DAYS));
days = converter.addWorkingDaysToInstant(thursday0201, Duration.ofDays(7)); // mon
assertThat(days).isEqualTo(thursday0201.plus(11, ChronoUnit.DAYS));
days = converter.addWorkingDaysToInstant(thursday0201, Duration.ofDays(8)); // tue
assertThat(days).isEqualTo(thursday0201.plus(12, ChronoUnit.DAYS));
days = converter.addWorkingDaysToInstant(thursday0201, Duration.ofDays(9)); // we
assertThat(days).isEqualTo(thursday0201.plus(13, ChronoUnit.DAYS));
days = converter.addWorkingDaysToInstant(thursday0201, Duration.ofDays(10)); // thu
assertThat(days).isEqualTo(thursday0201.plus(14, ChronoUnit.DAYS));
days = converter.addWorkingDaysToInstant(thursday0201, Duration.ofDays(11)); // fri
assertThat(days).isEqualTo(thursday0201.plus(15, ChronoUnit.DAYS));
}
@Test
void testConvertWorkingDaysToDaysForKarFreitag() {
Instant gruenDonnerstag2018 = Instant.parse("2018-03-29T01:00:00.000Z");
Instant days = converter.addWorkingDaysToInstant(gruenDonnerstag2018, Duration.ofDays(0));
assertThat(days).isEqualTo(gruenDonnerstag2018.plus(0, ChronoUnit.DAYS));
days = converter.addWorkingDaysToInstant(gruenDonnerstag2018, Duration.ofDays(1)); // Karfreitag
assertThat(days).isEqualTo(gruenDonnerstag2018.plus(5, ChronoUnit.DAYS)); // osterdienstag
days = converter.addWorkingDaysToInstant(gruenDonnerstag2018, Duration.ofDays(2)); // Karfreitag
assertThat(days).isEqualTo(gruenDonnerstag2018.plus(6, ChronoUnit.DAYS)); // ostermittwoch
}
@Test
void testConvertWorkingDaysToDaysForHolidays() {
Instant freitag0427 = Instant.parse("2018-04-27T19:00:00.000Z");
Instant days = converter.addWorkingDaysToInstant(freitag0427, Duration.ofDays(0));
assertThat(days).isEqualTo(freitag0427.plus(0, ChronoUnit.DAYS));
days = converter.addWorkingDaysToInstant(freitag0427, Duration.ofDays(1));
assertThat(days).isEqualTo(freitag0427.plus(3, ChronoUnit.DAYS)); // 30.4.
days = converter.addWorkingDaysToInstant(freitag0427, Duration.ofDays(2));
assertThat(days).isEqualTo(freitag0427.plus(5, ChronoUnit.DAYS)); // 2.5.
}
@Test
void testGetEasterSunday() {
EasterCalculator easterCalculator = new EasterCalculator();
assertThat(easterCalculator.getEasterSunday(2018)).isEqualTo(LocalDate.of(2018, 4, 1));
assertThat(easterCalculator.getEasterSunday(2019)).isEqualTo(LocalDate.of(2019, 4, 21));
assertThat(easterCalculator.getEasterSunday(2020)).isEqualTo(LocalDate.of(2020, 4, 12));
assertThat(easterCalculator.getEasterSunday(2021)).isEqualTo(LocalDate.of(2021, 4, 4));
assertThat(easterCalculator.getEasterSunday(2022)).isEqualTo(LocalDate.of(2022, 4, 17));
assertThat(easterCalculator.getEasterSunday(2023)).isEqualTo(LocalDate.of(2023, 4, 9));
assertThat(easterCalculator.getEasterSunday(2024)).isEqualTo(LocalDate.of(2024, 3, 31));
assertThat(easterCalculator.getEasterSunday(2025)).isEqualTo(LocalDate.of(2025, 4, 20));
assertThat(easterCalculator.getEasterSunday(2026)).isEqualTo(LocalDate.of(2026, 4, 5));
assertThat(easterCalculator.getEasterSunday(2027)).isEqualTo(LocalDate.of(2027, 3, 28));
assertThat(easterCalculator.getEasterSunday(2028)).isEqualTo(LocalDate.of(2028, 4, 16));
assertThat(easterCalculator.getEasterSunday(2029)).isEqualTo(LocalDate.of(2029, 4, 1));
assertThat(easterCalculator.getEasterSunday(2030)).isEqualTo(LocalDate.of(2030, 4, 21));
assertThat(easterCalculator.getEasterSunday(2031)).isEqualTo(LocalDate.of(2031, 4, 13));
assertThat(easterCalculator.getEasterSunday(2032)).isEqualTo(LocalDate.of(2032, 3, 28));
assertThat(easterCalculator.getEasterSunday(2033)).isEqualTo(LocalDate.of(2033, 4, 17));
assertThat(easterCalculator.getEasterSunday(2034)).isEqualTo(LocalDate.of(2034, 4, 9));
assertThat(easterCalculator.getEasterSunday(2035)).isEqualTo(LocalDate.of(2035, 3, 25));
assertThat(easterCalculator.getEasterSunday(2040)).isEqualTo(LocalDate.of(2040, 4, 1));
assertThat(easterCalculator.getEasterSunday(2050)).isEqualTo(LocalDate.of(2050, 4, 10));
assertThat(easterCalculator.getEasterSunday(2100)).isEqualTo(LocalDate.of(2100, 3, 28));
}
}

View File

@ -1,242 +0,0 @@
package pro.taskana.common.internal.util;
import static org.assertj.core.api.Assertions.assertThat;
import static pro.taskana.common.internal.util.WorkingDaysToDaysConverter.getEasterSunday;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Arrays;
import java.util.stream.Stream;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.DynamicContainer;
import org.junit.jupiter.api.DynamicNode;
import org.junit.jupiter.api.DynamicTest;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestFactory;
import pro.taskana.common.api.CustomHoliday;
import pro.taskana.common.api.exceptions.InvalidArgumentException;
/** Test for the WorkingDaysToDaysConverter. */
class WorkingDaysToDaysConverterTest {
@BeforeAll
static void setup() {
WorkingDaysToDaysConverter.setGermanPublicHolidaysEnabled(true);
CustomHoliday dayOfReformation = CustomHoliday.of(31, 10);
CustomHoliday allSaintsDays = CustomHoliday.of(1, 11);
WorkingDaysToDaysConverter.setCustomHolidays(Arrays.asList(dayOfReformation, allSaintsDays));
}
void verifyCorpusChristiForDate(
WorkingDaysToDaysConverter converter,
String date,
boolean enableCorpsChristi,
boolean expected) {
WorkingDaysToDaysConverter.setCorpusChristiEnabled(enableCorpsChristi);
Instant referenceDay = Instant.parse(date);
converter.refreshReferenceDate(referenceDay);
assertThat(
converter.isGermanHoliday(
LocalDateTime.ofInstant(referenceDay, ZoneId.systemDefault()).toLocalDate()))
.isEqualTo(expected);
WorkingDaysToDaysConverter.setCorpusChristiEnabled(false);
}
@TestFactory
Stream<DynamicNode> should_DetectCorpusChristiAsHoliday_When_CorpusChristiIsEnabled() {
WorkingDaysToDaysConverter converter = WorkingDaysToDaysConverter.initialize();
DynamicContainer enabledCorpusChristi =
DynamicContainer.dynamicContainer(
"corpus christi is enabled",
Stream.of(
DynamicTest.dynamicTest(
"year 1980",
() ->
verifyCorpusChristiForDate(
converter, "1980-06-05T12:00:00.000Z", true, true)),
DynamicTest.dynamicTest(
"year 2020",
() ->
verifyCorpusChristiForDate(
converter, "2020-06-11T12:00:00.000Z", true, true))));
DynamicContainer disabledCorpusChristi =
DynamicContainer.dynamicContainer(
"corpus christi is enabled",
Stream.of(
DynamicTest.dynamicTest(
"year 1980",
() ->
verifyCorpusChristiForDate(
converter, "1980-06-05T12:00:00.000Z", false, false)),
DynamicTest.dynamicTest(
"year 2020",
() ->
verifyCorpusChristiForDate(
converter, "2020-06-11T12:00:00.000Z", false, false))));
return Stream.of(enabledCorpusChristi, disabledCorpusChristi);
}
@TestFactory
Stream<DynamicNode> testHasWorkingInBetween() throws InvalidArgumentException {
Instant referenceDay = Instant.parse("2020-02-01T07:00:00.000Z");
WorkingDaysToDaysConverter converter = WorkingDaysToDaysConverter.initialize(referenceDay);
Instant thursday = Instant.parse("2020-04-30T07:12:00.000Z");
Instant friday = Instant.parse("2020-05-01T07:12:00.000Z"); // german holiday
Instant saturday = Instant.parse("2020-05-02T07:12:00.000Z");
Instant sunday = Instant.parse("2020-05-03T07:12:00.000Z");
Instant monday = Instant.parse("2020-05-04T07:12:00.000Z");
Instant tuesday = Instant.parse("2020-05-05T07:12:00.000Z");
DynamicContainer noWorkingDaysInBetween =
DynamicContainer.dynamicContainer(
"no working days in between",
Stream.of(
DynamicTest.dynamicTest(
"tuesday <-> tuesday",
() ->
assertThat(converter.hasWorkingDaysInBetween(tuesday, tuesday)).isFalse()),
DynamicTest.dynamicTest(
"thursday <-> saturday (friday is holiday)",
() ->
assertThat(converter.hasWorkingDaysInBetween(thursday, saturday))
.isFalse()),
DynamicTest.dynamicTest(
"friday <-> friday",
() -> assertThat(converter.hasWorkingDaysInBetween(friday, friday)).isFalse()),
DynamicTest.dynamicTest(
"friday <-> monday",
() -> assertThat(converter.hasWorkingDaysInBetween(friday, monday)).isFalse()),
DynamicTest.dynamicTest(
"saturday <-> monday",
() ->
assertThat(converter.hasWorkingDaysInBetween(saturday, monday)).isFalse()),
DynamicTest.dynamicTest(
"sunday <-> monday",
() -> assertThat(converter.hasWorkingDaysInBetween(sunday, monday)).isFalse()),
DynamicTest.dynamicTest(
"monday <-> monday",
() -> assertThat(converter.hasWorkingDaysInBetween(sunday, monday)).isFalse()),
DynamicTest.dynamicTest(
"monday <-> sunday",
() -> assertThat(converter.hasWorkingDaysInBetween(monday, sunday)).isFalse()),
DynamicTest.dynamicTest(
"monday <-> friday",
() ->
assertThat(converter.hasWorkingDaysInBetween(monday, friday)).isFalse())));
DynamicContainer hasWorkingDaysInBetween =
DynamicContainer.dynamicContainer(
"has working days in between",
Stream.of(
DynamicTest.dynamicTest(
"friday <-> tuesday",
() -> assertThat(converter.hasWorkingDaysInBetween(friday, tuesday)).isTrue()),
DynamicTest.dynamicTest(
"sunday <-> tuesday",
() ->
assertThat(converter.hasWorkingDaysInBetween(sunday, tuesday)).isTrue())));
return Stream.of(noWorkingDaysInBetween, hasWorkingDaysInBetween);
}
@Test
void testConvertWorkingDaysToDaysForTasks() throws InvalidArgumentException {
Instant thursday0201 = Instant.parse("2018-02-01T07:00:00.000Z");
WorkingDaysToDaysConverter converter = WorkingDaysToDaysConverter.initialize(thursday0201);
long days = converter.convertWorkingDaysToDays(thursday0201, -7); // = tuesday (sat + sun)
assertThat(days).isEqualTo(-9);
days = converter.convertWorkingDaysToDays(thursday0201, -6); // = wednesday (sat + sun)
assertThat(days).isEqualTo(-8);
days = converter.convertWorkingDaysToDays(thursday0201, -5); // = thursday (sat + sun)
assertThat(days).isEqualTo(-7);
days = converter.convertWorkingDaysToDays(thursday0201, -4); // = friday
assertThat(days).isEqualTo(-6);
days = converter.convertWorkingDaysToDays(thursday0201, -3); // monday
assertThat(days).isEqualTo(-3);
days = converter.convertWorkingDaysToDays(thursday0201, -2); // tuesday
assertThat(days).isEqualTo(-2);
days = converter.convertWorkingDaysToDays(thursday0201, -1); // wednesday
assertThat(days).isEqualTo(-1);
days = converter.convertWorkingDaysToDays(thursday0201, 0); // = thursday
assertThat(days).isEqualTo(0);
days = converter.convertWorkingDaysToDays(thursday0201, 1); // fri
assertThat(days).isEqualTo(1);
days = converter.convertWorkingDaysToDays(thursday0201, 2); // mon
assertThat(days).isEqualTo(4);
days = converter.convertWorkingDaysToDays(thursday0201, 3); // tues
assertThat(days).isEqualTo(5);
days = converter.convertWorkingDaysToDays(thursday0201, 4); // we
assertThat(days).isEqualTo(6);
days = converter.convertWorkingDaysToDays(thursday0201, 5); // thurs
assertThat(days).isEqualTo(7);
days = converter.convertWorkingDaysToDays(thursday0201, 6); // fri
assertThat(days).isEqualTo(8);
days = converter.convertWorkingDaysToDays(thursday0201, 7); // mon
assertThat(days).isEqualTo(11);
days = converter.convertWorkingDaysToDays(thursday0201, 8); // tue
assertThat(days).isEqualTo(12);
days = converter.convertWorkingDaysToDays(thursday0201, 9); // we
assertThat(days).isEqualTo(13);
days = converter.convertWorkingDaysToDays(thursday0201, 10); // thu
assertThat(days).isEqualTo(14);
days = converter.convertWorkingDaysToDays(thursday0201, 11); // fri
assertThat(days).isEqualTo(15);
}
@Test
void testConvertWorkingDaysToDaysForKarFreitag() throws InvalidArgumentException {
Instant thursday0201 = Instant.parse("2018-02-01T07:00:00.000Z");
WorkingDaysToDaysConverter converter = WorkingDaysToDaysConverter.initialize(thursday0201);
Instant gruenDonnerstag2018 = Instant.parse("2018-03-29T01:00:00.000Z");
long days = converter.convertWorkingDaysToDays(gruenDonnerstag2018, 0);
assertThat(days).isEqualTo(0);
days = converter.convertWorkingDaysToDays(gruenDonnerstag2018, 1); // Karfreitag
assertThat(days).isEqualTo(5); // osterdienstag
days = converter.convertWorkingDaysToDays(gruenDonnerstag2018, 2); // Karfreitag
assertThat(days).isEqualTo(6); // ostermittwoch
}
@Test
void testConvertWorkingDaysToDaysForHolidays() throws InvalidArgumentException {
Instant thursday0201 = Instant.parse("2018-02-01T07:00:00.000Z");
WorkingDaysToDaysConverter converter = WorkingDaysToDaysConverter.initialize(thursday0201);
Instant freitag0427 = Instant.parse("2018-04-27T19:00:00.000Z");
long days = converter.convertWorkingDaysToDays(freitag0427, 0);
assertThat(days).isEqualTo(0);
days = converter.convertWorkingDaysToDays(freitag0427, 1);
assertThat(days).isEqualTo(3); // 30.4.
days = converter.convertWorkingDaysToDays(freitag0427, 2);
assertThat(days).isEqualTo(5); // 2.5.
}
@Test
void testGetEasterSunday() {
assertThat(getEasterSunday(2018)).isEqualTo(LocalDate.of(2018, 4, 1));
assertThat(getEasterSunday(2019)).isEqualTo(LocalDate.of(2019, 4, 21));
assertThat(getEasterSunday(2020)).isEqualTo(LocalDate.of(2020, 4, 12));
assertThat(getEasterSunday(2021)).isEqualTo(LocalDate.of(2021, 4, 4));
assertThat(getEasterSunday(2022)).isEqualTo(LocalDate.of(2022, 4, 17));
assertThat(getEasterSunday(2023)).isEqualTo(LocalDate.of(2023, 4, 9));
assertThat(getEasterSunday(2024)).isEqualTo(LocalDate.of(2024, 3, 31));
assertThat(getEasterSunday(2025)).isEqualTo(LocalDate.of(2025, 4, 20));
assertThat(getEasterSunday(2026)).isEqualTo(LocalDate.of(2026, 4, 5));
assertThat(getEasterSunday(2027)).isEqualTo(LocalDate.of(2027, 3, 28));
assertThat(getEasterSunday(2028)).isEqualTo(LocalDate.of(2028, 4, 16));
assertThat(getEasterSunday(2029)).isEqualTo(LocalDate.of(2029, 4, 1));
assertThat(getEasterSunday(2030)).isEqualTo(LocalDate.of(2030, 4, 21));
assertThat(getEasterSunday(2031)).isEqualTo(LocalDate.of(2031, 4, 13));
assertThat(getEasterSunday(2032)).isEqualTo(LocalDate.of(2032, 3, 28));
assertThat(getEasterSunday(2033)).isEqualTo(LocalDate.of(2033, 4, 17));
assertThat(getEasterSunday(2034)).isEqualTo(LocalDate.of(2034, 4, 9));
assertThat(getEasterSunday(2035)).isEqualTo(LocalDate.of(2035, 3, 25));
assertThat(getEasterSunday(2040)).isEqualTo(LocalDate.of(2040, 4, 1));
assertThat(getEasterSunday(2050)).isEqualTo(LocalDate.of(2050, 4, 10));
assertThat(getEasterSunday(2100)).isEqualTo(LocalDate.of(2100, 3, 28));
}
}

View File

@ -49,10 +49,7 @@ class CategoryReportBuilderImplTest {
@BeforeEach
void setup() {
when(taskanaEngineMock.getConfiguration()).thenReturn(taskanaEngineConfiguration);
when(internalTaskanaEngineMock.getEngine()).thenReturn(taskanaEngineMock);
when(taskanaEngineConfiguration.isGermanPublicHolidaysEnabled()).thenReturn(true);
when(taskanaEngineConfiguration.getCustomHolidays()).thenReturn(null);
}
@Test
@ -97,10 +94,7 @@ class CategoryReportBuilderImplTest {
verify(internalTaskanaEngineMock).openConnection();
verify(internalTaskanaEngineMock, times(2)).getEngine();
verify(taskanaEngineMock).checkRoleMembership(any());
verify(taskanaEngineMock).getConfiguration();
verify(taskanaEngineConfiguration).isGermanPublicHolidaysEnabled();
verify(taskanaEngineConfiguration).isCorpusChristiEnabled();
verify(taskanaEngineConfiguration).getCustomHolidays();
verify(taskanaEngineMock).getWorkingDaysToDaysConverter();
verify(monitorMapperMock)
.getTaskCountOfCategories(any(), any(), any(), any(), any(), any(), any());
verify(internalTaskanaEngineMock).returnConnection();
@ -161,10 +155,7 @@ class CategoryReportBuilderImplTest {
verify(internalTaskanaEngineMock).openConnection();
verify(internalTaskanaEngineMock, times(2)).getEngine();
verify(taskanaEngineMock).checkRoleMembership(any());
verify(taskanaEngineMock).getConfiguration();
verify(taskanaEngineConfiguration).isGermanPublicHolidaysEnabled();
verify(taskanaEngineConfiguration).isCorpusChristiEnabled();
verify(taskanaEngineConfiguration).getCustomHolidays();
verify(taskanaEngineMock).getWorkingDaysToDaysConverter();
verify(monitorMapperMock)
.getTaskCountOfCategories(any(), any(), any(), any(), any(), any(), any());
verify(internalTaskanaEngineMock).returnConnection();
@ -231,10 +222,7 @@ class CategoryReportBuilderImplTest {
verify(internalTaskanaEngineMock).openConnection();
verify(internalTaskanaEngineMock, times(2)).getEngine();
verify(taskanaEngineMock).checkRoleMembership(any());
verify(taskanaEngineMock).getConfiguration();
verify(taskanaEngineConfiguration).isGermanPublicHolidaysEnabled();
verify(taskanaEngineConfiguration).isCorpusChristiEnabled();
verify(taskanaEngineConfiguration).getCustomHolidays();
verify(taskanaEngineMock).getWorkingDaysToDaysConverter();
verify(monitorMapperMock)
.getTaskIdsForSelectedItems(
any(), any(), any(), any(), any(), any(), any(), any(), any(), eq(false));
@ -305,10 +293,7 @@ class CategoryReportBuilderImplTest {
verify(internalTaskanaEngineMock).openConnection();
verify(internalTaskanaEngineMock, times(2)).getEngine();
verify(taskanaEngineMock).checkRoleMembership(any());
verify(taskanaEngineMock).getConfiguration();
verify(taskanaEngineConfiguration).isGermanPublicHolidaysEnabled();
verify(taskanaEngineConfiguration).isCorpusChristiEnabled();
verify(taskanaEngineConfiguration).getCustomHolidays();
verify(taskanaEngineMock).getWorkingDaysToDaysConverter();
verify(monitorMapperMock)
.getCustomAttributeValuesForReport(any(), any(), any(), any(), any(), any(), any(), any());
verify(internalTaskanaEngineMock).returnConnection();
@ -327,7 +312,7 @@ class CategoryReportBuilderImplTest {
throws NotAuthorizedException {
List<String> result =
cut.createCategoryReportBuilder()
.workbasketIdIn(Arrays.asList("DieGibtsSicherNed"))
.workbasketIdIn(Collections.singletonList("DieGibtsSicherNed"))
.listCustomAttributeValuesForCustomAttributeName(CustomField.CUSTOM_1);
assertThat(result).isNotNull();
}

View File

@ -53,9 +53,6 @@ class ClassificationReportBuilderImplTest {
@BeforeEach
void setup() {
when(internalTaskanaEngineMock.getEngine()).thenReturn(taskanaEngineMock);
when(taskanaEngineMock.getConfiguration()).thenReturn(taskanaEngineConfiguration);
when(taskanaEngineConfiguration.isGermanPublicHolidaysEnabled()).thenReturn(true);
when(taskanaEngineConfiguration.getCustomHolidays()).thenReturn(null);
}
@Test
@ -99,12 +96,9 @@ class ClassificationReportBuilderImplTest {
verify(internalTaskanaEngineMock).openConnection();
verify(taskanaEngineMock).checkRoleMembership(any());
verify(taskanaEngineMock).getConfiguration();
verify(taskanaEngineMock).getWorkingDaysToDaysConverter();
verify(internalTaskanaEngineMock, times(2)).getEngine();
verify(taskanaEngineConfiguration).isGermanPublicHolidaysEnabled();
verify(taskanaEngineConfiguration).isCorpusChristiEnabled();
verify(taskanaEngineConfiguration).getCustomHolidays();
verify(monitorMapperMock)
.getTaskCountOfClassifications(any(), any(), any(), any(), any(), any(), any());
verify(internalTaskanaEngineMock).returnConnection();
@ -166,12 +160,9 @@ class ClassificationReportBuilderImplTest {
verify(internalTaskanaEngineMock).openConnection();
verify(taskanaEngineMock).checkRoleMembership(any());
verify(taskanaEngineMock).getConfiguration();
verify(taskanaEngineMock).getWorkingDaysToDaysConverter();
verify(internalTaskanaEngineMock, times(2)).getEngine();
verify(taskanaEngineConfiguration).isGermanPublicHolidaysEnabled();
verify(taskanaEngineConfiguration).isCorpusChristiEnabled();
verify(taskanaEngineConfiguration).getCustomHolidays();
verify(monitorMapperMock)
.getTaskCountOfClassifications(any(), any(), any(), any(), any(), any(), any());
verify(internalTaskanaEngineMock).returnConnection();
@ -231,12 +222,9 @@ class ClassificationReportBuilderImplTest {
verify(internalTaskanaEngineMock).openConnection();
verify(taskanaEngineMock).checkRoleMembership(any());
verify(taskanaEngineMock).getConfiguration();
verify(taskanaEngineMock).getWorkingDaysToDaysConverter();
verify(internalTaskanaEngineMock, times(2)).getEngine();
verify(taskanaEngineConfiguration).isGermanPublicHolidaysEnabled();
verify(taskanaEngineConfiguration).isCorpusChristiEnabled();
verify(taskanaEngineConfiguration).getCustomHolidays();
verify(monitorMapperMock)
.getTaskCountOfDetailedClassifications(any(), any(), any(), any(), any(), any(), any());
verify(internalTaskanaEngineMock).returnConnection();
@ -301,12 +289,9 @@ class ClassificationReportBuilderImplTest {
verify(internalTaskanaEngineMock).openConnection();
verify(taskanaEngineMock).checkRoleMembership(any());
verify(taskanaEngineMock).getConfiguration();
verify(taskanaEngineMock).getWorkingDaysToDaysConverter();
verify(internalTaskanaEngineMock, times(2)).getEngine();
verify(taskanaEngineConfiguration).isGermanPublicHolidaysEnabled();
verify(taskanaEngineConfiguration).isCorpusChristiEnabled();
verify(taskanaEngineConfiguration).getCustomHolidays();
verify(monitorMapperMock)
.getTaskCountOfDetailedClassifications(any(), any(), any(), any(), any(), any(), any());
verify(internalTaskanaEngineMock).returnConnection();
@ -378,12 +363,9 @@ class ClassificationReportBuilderImplTest {
verify(internalTaskanaEngineMock).openConnection();
verify(taskanaEngineMock).checkRoleMembership(any());
verify(taskanaEngineMock).getConfiguration();
verify(taskanaEngineMock).getWorkingDaysToDaysConverter();
verify(internalTaskanaEngineMock, times(2)).getEngine();
verify(taskanaEngineConfiguration).isGermanPublicHolidaysEnabled();
verify(taskanaEngineConfiguration).isCorpusChristiEnabled();
verify(taskanaEngineConfiguration).getCustomHolidays();
verify(monitorMapperMock)
.getTaskIdsForSelectedItems(
any(), any(), any(), any(), any(), any(), any(), any(), any(), eq(false));
@ -406,7 +388,7 @@ class ClassificationReportBuilderImplTest {
List<SelectedItem> selectedItems = Collections.singletonList(selectedItem);
List<String> result =
cut.createClassificationReportBuilder()
.workbasketIdIn(Arrays.asList("DieGibtsEhNed"))
.workbasketIdIn(Collections.singletonList("DieGibtsEhNed"))
.listTaskIdsForSelectedItems(selectedItems);
assertThat(result).isNotNull();
}
@ -456,12 +438,9 @@ class ClassificationReportBuilderImplTest {
verify(internalTaskanaEngineMock).openConnection();
verify(taskanaEngineMock).checkRoleMembership(any());
verify(taskanaEngineMock).getConfiguration();
verify(taskanaEngineMock).getWorkingDaysToDaysConverter();
verify(internalTaskanaEngineMock, times(2)).getEngine();
verify(taskanaEngineConfiguration).isGermanPublicHolidaysEnabled();
verify(taskanaEngineConfiguration).isCorpusChristiEnabled();
verify(taskanaEngineConfiguration).getCustomHolidays();
verify(monitorMapperMock)
.getCustomAttributeValuesForReport(any(), any(), any(), any(), any(), any(), any(), any());
verify(internalTaskanaEngineMock).returnConnection();

View File

@ -49,9 +49,6 @@ class CustomFieldValueReportBuilderImplTest {
@BeforeEach
void setup() {
when(internalTaskanaEngineMock.getEngine()).thenReturn(taskanaEngineMock);
when(taskanaEngineMock.getConfiguration()).thenReturn(taskanaEngineConfigurationMock);
when(taskanaEngineConfigurationMock.isGermanPublicHolidaysEnabled()).thenReturn(true);
when(taskanaEngineConfigurationMock.getCustomHolidays()).thenReturn(null);
}
@Test
@ -96,11 +93,8 @@ class CustomFieldValueReportBuilderImplTest {
verify(internalTaskanaEngineMock).openConnection();
verify(taskanaEngineMock).checkRoleMembership(any());
verify(taskanaEngineMock).getConfiguration();
verify(taskanaEngineMock).getWorkingDaysToDaysConverter();
verify(internalTaskanaEngineMock, times(2)).getEngine();
verify(taskanaEngineConfigurationMock).isGermanPublicHolidaysEnabled();
verify(taskanaEngineConfigurationMock).isCorpusChristiEnabled();
verify(taskanaEngineConfigurationMock).getCustomHolidays();
verify(monitorMapperMock)
.getTaskCountOfCustomFieldValues(any(), any(), any(), any(), any(), any(), any(), any());
verify(internalTaskanaEngineMock).returnConnection();
@ -161,11 +155,8 @@ class CustomFieldValueReportBuilderImplTest {
verify(internalTaskanaEngineMock).openConnection();
verify(taskanaEngineMock).checkRoleMembership(any());
verify(taskanaEngineMock).getConfiguration();
verify(taskanaEngineMock).getWorkingDaysToDaysConverter();
verify(internalTaskanaEngineMock, times(2)).getEngine();
verify(taskanaEngineConfigurationMock).isGermanPublicHolidaysEnabled();
verify(taskanaEngineConfigurationMock).isCorpusChristiEnabled();
verify(taskanaEngineConfigurationMock).getCustomHolidays();
verify(monitorMapperMock)
.getTaskCountOfCustomFieldValues(any(), any(), any(), any(), any(), any(), any(), any());
verify(internalTaskanaEngineMock).returnConnection();
@ -226,11 +217,8 @@ class CustomFieldValueReportBuilderImplTest {
verify(internalTaskanaEngineMock).openConnection();
verify(taskanaEngineMock).checkRoleMembership(any());
verify(taskanaEngineMock).getConfiguration();
verify(taskanaEngineMock).getWorkingDaysToDaysConverter();
verify(internalTaskanaEngineMock, times(2)).getEngine();
verify(taskanaEngineConfigurationMock).isGermanPublicHolidaysEnabled();
verify(taskanaEngineConfigurationMock).isCorpusChristiEnabled();
verify(taskanaEngineConfigurationMock).getCustomHolidays();
verify(monitorMapperMock)
.getCustomAttributeValuesForReport(any(), any(), any(), any(), any(), any(), any(), any());
verify(internalTaskanaEngineMock).returnConnection();

View File

@ -23,7 +23,6 @@ import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import pro.taskana.TaskanaEngineConfiguration;
import pro.taskana.common.api.TaskanaEngine;
import pro.taskana.common.api.TaskanaRole;
import pro.taskana.common.api.exceptions.InvalidArgumentException;
@ -47,16 +46,11 @@ class WorkbasketReportBuilderImplTest {
@Mock private TaskanaEngine taskanaEngineMock;
@Mock private TaskanaEngineConfiguration taskanaEngineConfiguration;
@Mock private MonitorMapper monitorMapperMock;
@BeforeEach
void setup() {
when(internalTaskanaEngineMock.getEngine()).thenReturn(taskanaEngineMock);
when(taskanaEngineMock.getConfiguration()).thenReturn(taskanaEngineConfiguration);
when(taskanaEngineConfiguration.isGermanPublicHolidaysEnabled()).thenReturn(true);
when(taskanaEngineConfiguration.getCustomHolidays()).thenReturn(null);
}
@Test
@ -107,19 +101,12 @@ class WorkbasketReportBuilderImplTest {
verify(internalTaskanaEngineMock).openConnection();
verify(taskanaEngineMock).checkRoleMembership(any());
verify(taskanaEngineMock).getConfiguration();
verify(taskanaEngineMock).getWorkingDaysToDaysConverter();
verify(internalTaskanaEngineMock, times(2)).getEngine();
verify(taskanaEngineConfiguration).isGermanPublicHolidaysEnabled();
verify(taskanaEngineConfiguration).isCorpusChristiEnabled();
verify(taskanaEngineConfiguration).getCustomHolidays();
verify(monitorMapperMock)
.getTaskCountOfWorkbaskets(any(), any(), any(), any(), any(), any(), any(), any());
verify(internalTaskanaEngineMock).returnConnection();
verifyNoMoreInteractions(
internalTaskanaEngineMock,
taskanaEngineMock,
monitorMapperMock,
taskanaEngineConfiguration);
verifyNoMoreInteractions(internalTaskanaEngineMock, taskanaEngineMock, monitorMapperMock);
assertThat(actualResult).isNotNull();
assertThat(actualResult.getRow("WBI:000000000000000000000000000000000001").getTotalValue())
@ -179,19 +166,12 @@ class WorkbasketReportBuilderImplTest {
verify(internalTaskanaEngineMock).openConnection();
verify(taskanaEngineMock).checkRoleMembership(any());
verify(taskanaEngineMock).getConfiguration();
verify(taskanaEngineMock).getWorkingDaysToDaysConverter();
verify(internalTaskanaEngineMock, times(2)).getEngine();
verify(taskanaEngineConfiguration).isGermanPublicHolidaysEnabled();
verify(taskanaEngineConfiguration).isCorpusChristiEnabled();
verify(taskanaEngineConfiguration).getCustomHolidays();
verify(monitorMapperMock)
.getTaskCountOfWorkbaskets(any(), any(), any(), any(), any(), any(), any(), any());
verify(internalTaskanaEngineMock).returnConnection();
verifyNoMoreInteractions(
internalTaskanaEngineMock,
taskanaEngineMock,
monitorMapperMock,
taskanaEngineConfiguration);
verifyNoMoreInteractions(internalTaskanaEngineMock, taskanaEngineMock, monitorMapperMock);
assertThat(actualResult).isNotNull();
assertThat(actualResult.getRow("WBI:000000000000000000000000000000000001").getTotalValue())
@ -251,20 +231,13 @@ class WorkbasketReportBuilderImplTest {
verify(internalTaskanaEngineMock).openConnection();
verify(taskanaEngineMock).checkRoleMembership(any());
verify(taskanaEngineMock).getConfiguration();
verify(taskanaEngineMock).getWorkingDaysToDaysConverter();
verify(internalTaskanaEngineMock, times(2)).getEngine();
verify(taskanaEngineConfiguration).isGermanPublicHolidaysEnabled();
verify(taskanaEngineConfiguration).isCorpusChristiEnabled();
verify(taskanaEngineConfiguration).getCustomHolidays();
verify(monitorMapperMock)
.getTaskIdsForSelectedItems(
any(), any(), any(), any(), any(), any(), any(), any(), any(), eq(false));
verify(internalTaskanaEngineMock).returnConnection();
verifyNoMoreInteractions(
internalTaskanaEngineMock,
taskanaEngineMock,
monitorMapperMock,
taskanaEngineConfiguration);
verifyNoMoreInteractions(internalTaskanaEngineMock, taskanaEngineMock, monitorMapperMock);
assertThat(actualResult).isNotNull();
assertThat(actualResult).isEqualTo(expectedResult);
@ -277,7 +250,7 @@ class WorkbasketReportBuilderImplTest {
() -> {
List<String> result =
cut.createWorkbasketReportBuilder()
.workbasketIdIn(Arrays.asList("DieGibtsGarantiertNed"))
.workbasketIdIn(Collections.singletonList("DieGibtsGarantiertNed"))
.listTaskIdsForSelectedItems(selectedItems);
assertThat(result).isNotNull();
};
@ -329,19 +302,12 @@ class WorkbasketReportBuilderImplTest {
verify(internalTaskanaEngineMock).openConnection();
verify(taskanaEngineMock).checkRoleMembership(any());
verify(taskanaEngineMock).getConfiguration();
verify(taskanaEngineMock).getWorkingDaysToDaysConverter();
verify(internalTaskanaEngineMock, times(2)).getEngine();
verify(taskanaEngineConfiguration).isGermanPublicHolidaysEnabled();
verify(taskanaEngineConfiguration).isCorpusChristiEnabled();
verify(taskanaEngineConfiguration).getCustomHolidays();
verify(monitorMapperMock)
.getCustomAttributeValuesForReport(any(), any(), any(), any(), any(), any(), any(), any());
verify(internalTaskanaEngineMock).returnConnection();
verifyNoMoreInteractions(
internalTaskanaEngineMock,
taskanaEngineMock,
monitorMapperMock,
taskanaEngineConfiguration);
verifyNoMoreInteractions(internalTaskanaEngineMock, taskanaEngineMock, monitorMapperMock);
assertThat(actualResult).isNotNull();
assertThat(actualResult).isEqualTo(expectedResult);
@ -405,11 +371,8 @@ class WorkbasketReportBuilderImplTest {
verify(internalTaskanaEngineMock).openConnection();
verify(taskanaEngineMock).checkRoleMembership(TaskanaRole.MONITOR, TaskanaRole.ADMIN);
verify(taskanaEngineMock).getConfiguration();
verify(taskanaEngineMock).getWorkingDaysToDaysConverter();
verify(internalTaskanaEngineMock, times(2)).getEngine();
verify(taskanaEngineConfiguration).isGermanPublicHolidaysEnabled();
verify(taskanaEngineConfiguration).isCorpusChristiEnabled();
verify(taskanaEngineConfiguration).getCustomHolidays();
verify(monitorMapperMock)
.getTaskCountOfWorkbasketsBasedOnPlannedDate(
workbasketIds,
@ -421,11 +384,7 @@ class WorkbasketReportBuilderImplTest {
customAttributeFilter,
combinedClassificationFilter);
verify(internalTaskanaEngineMock).returnConnection();
verifyNoMoreInteractions(
internalTaskanaEngineMock,
taskanaEngineMock,
monitorMapperMock,
taskanaEngineConfiguration);
verifyNoMoreInteractions(internalTaskanaEngineMock, taskanaEngineMock, monitorMapperMock);
assertThat(actualResult).isNotNull();
assertThat(actualResult.getRow("WBI:000000000000000000000000000000000001").getTotalValue())

View File

@ -6,34 +6,34 @@ import java.time.Instant;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import pro.taskana.common.api.CustomHoliday;
import pro.taskana.common.api.WorkingDaysToDaysConverter;
import pro.taskana.common.api.exceptions.InvalidArgumentException;
import pro.taskana.common.internal.util.WorkingDaysToDaysConverter;
import pro.taskana.monitor.api.reports.header.TimeIntervalColumnHeader;
import pro.taskana.monitor.internal.preprocessor.WorkingDaysToDaysReportConverter;
/** Test for the DaysToWorkingDaysReportConverter. */
class WorkingDaysToDaysReportConverterTest {
@BeforeAll
static void setup() {
WorkingDaysToDaysConverter.setGermanPublicHolidaysEnabled(true);
private final WorkingDaysToDaysConverter converter;
public WorkingDaysToDaysReportConverterTest() {
CustomHoliday dayOfReformation = CustomHoliday.of(31, 10);
CustomHoliday allSaintsDays = CustomHoliday.of(1, 11);
WorkingDaysToDaysConverter.setCustomHolidays(Arrays.asList(dayOfReformation, allSaintsDays));
converter =
new WorkingDaysToDaysConverter(true, false, Arrays.asList(dayOfReformation, allSaintsDays));
}
@Test
void should_AssertNotEqual_When_InitializingDifferentDates() throws InvalidArgumentException {
WorkingDaysToDaysReportConverter instance1 =
WorkingDaysToDaysReportConverter.initialize(
getShortListOfColumnHeaders(), Instant.parse("2018-02-04T00:00:00.000Z"));
getShortListOfColumnHeaders(), converter, Instant.parse("2018-02-04T00:00:00.000Z"));
WorkingDaysToDaysReportConverter instance2 =
WorkingDaysToDaysReportConverter.initialize(
getShortListOfColumnHeaders(), Instant.parse("2018-02-05T00:00:00.000Z"));
getShortListOfColumnHeaders(), converter, Instant.parse("2018-02-05T00:00:00.000Z"));
assertThat(instance1).isNotEqualTo(instance2);
}
@ -42,7 +42,7 @@ class WorkingDaysToDaysReportConverterTest {
void should_ReturnWorkingDays_When_ConvertingDaysToWorkingDays() throws InvalidArgumentException {
WorkingDaysToDaysReportConverter instance =
WorkingDaysToDaysReportConverter.initialize(
getLargeListOfColumnHeaders(), Instant.parse("2018-02-06T00:00:00.000Z"));
getLargeListOfColumnHeaders(), converter, Instant.parse("2018-02-06T00:00:00.000Z"));
int oneBelowLimit = -16;
int oneAboveLimit = 16;
@ -71,7 +71,7 @@ class WorkingDaysToDaysReportConverterTest {
throws InvalidArgumentException {
WorkingDaysToDaysReportConverter instance =
WorkingDaysToDaysReportConverter.initialize(
getLargeListOfColumnHeaders(), Instant.parse("2018-02-06T00:00:00.000Z"));
getLargeListOfColumnHeaders(), converter, Instant.parse("2018-02-06T00:00:00.000Z"));
assertThat(instance.convertWorkingDaysToDays(-999)).containsExactlyInAnyOrder(-999);
}
@ -81,7 +81,7 @@ class WorkingDaysToDaysReportConverterTest {
throws InvalidArgumentException {
WorkingDaysToDaysReportConverter instance =
WorkingDaysToDaysReportConverter.initialize(
getLargeListOfColumnHeaders(), Instant.parse("2018-02-06T00:00:00.000Z"));
getLargeListOfColumnHeaders(), converter, Instant.parse("2018-02-06T00:00:00.000Z"));
assertThat(instance.convertWorkingDaysToDays(999)).containsExactlyInAnyOrder(999);
}
@ -91,7 +91,7 @@ class WorkingDaysToDaysReportConverterTest {
throws InvalidArgumentException {
WorkingDaysToDaysReportConverter instance =
WorkingDaysToDaysReportConverter.initialize(
getLargeListOfColumnHeaders(), Instant.parse("2018-02-27T00:00:00.000Z"));
getLargeListOfColumnHeaders(), converter, Instant.parse("2018-02-27T00:00:00.000Z"));
assertThat(instance.convertWorkingDaysToDays(-13)).containsExactlyInAnyOrder(-13);
assertThat(instance.convertWorkingDaysToDays(-12)).containsExactlyInAnyOrder(-12);
@ -126,7 +126,7 @@ class WorkingDaysToDaysReportConverterTest {
throws InvalidArgumentException {
WorkingDaysToDaysReportConverter instance =
WorkingDaysToDaysReportConverter.initialize(
getLargeListOfColumnHeaders(), Instant.parse("2018-03-10T00:00:00.000Z"));
getLargeListOfColumnHeaders(), converter, Instant.parse("2018-03-10T00:00:00.000Z"));
assertThat(instance.convertWorkingDaysToDays(-13)).containsExactlyInAnyOrder(-13);
assertThat(instance.convertWorkingDaysToDays(-12)).containsExactlyInAnyOrder(-12);
@ -161,7 +161,7 @@ class WorkingDaysToDaysReportConverterTest {
throws InvalidArgumentException {
WorkingDaysToDaysReportConverter instance =
WorkingDaysToDaysReportConverter.initialize(
getLargeListOfColumnHeaders(), Instant.parse("2018-04-01T00:00:00.000Z"));
getLargeListOfColumnHeaders(), converter, Instant.parse("2018-04-01T00:00:00.000Z"));
assertThat(instance.convertWorkingDaysToDays(-13)).containsExactlyInAnyOrder(-13);
assertThat(instance.convertWorkingDaysToDays(-12)).containsExactlyInAnyOrder(-12);
@ -196,7 +196,7 @@ class WorkingDaysToDaysReportConverterTest {
throws InvalidArgumentException {
WorkingDaysToDaysReportConverter instance =
WorkingDaysToDaysReportConverter.initialize(
getLargeListOfColumnHeaders(), Instant.parse("2018-03-28T00:00:00.000Z"));
getLargeListOfColumnHeaders(), converter, Instant.parse("2018-03-28T00:00:00.000Z"));
assertThat(instance.convertDaysToWorkingDays(0)).isEqualTo(0);
assertThat(instance.convertDaysToWorkingDays(1)).isEqualTo(1);
@ -212,7 +212,7 @@ class WorkingDaysToDaysReportConverterTest {
throws InvalidArgumentException {
WorkingDaysToDaysReportConverter instance =
WorkingDaysToDaysReportConverter.initialize(
getLargeListOfColumnHeaders(), Instant.parse("2018-05-16T00:00:00.000Z"));
getLargeListOfColumnHeaders(), converter, Instant.parse("2018-05-16T00:00:00.000Z"));
assertThat(instance.convertDaysToWorkingDays(0)).isEqualTo(0);
assertThat(instance.convertDaysToWorkingDays(1)).isEqualTo(1);
@ -228,7 +228,7 @@ class WorkingDaysToDaysReportConverterTest {
throws InvalidArgumentException {
WorkingDaysToDaysReportConverter instance =
WorkingDaysToDaysReportConverter.initialize(
getLargeListOfColumnHeaders(), Instant.parse("2018-04-26T00:00:00.000Z"));
getLargeListOfColumnHeaders(), converter, Instant.parse("2018-04-26T00:00:00.000Z"));
assertThat(instance.convertDaysToWorkingDays(0)).isEqualTo(0);
assertThat(instance.convertDaysToWorkingDays(1)).isEqualTo(1);
@ -245,7 +245,7 @@ class WorkingDaysToDaysReportConverterTest {
throws InvalidArgumentException {
WorkingDaysToDaysReportConverter instance =
WorkingDaysToDaysReportConverter.initialize(
getLargeListOfColumnHeaders(), Instant.parse("2018-05-07T00:00:00.000Z"));
getLargeListOfColumnHeaders(), converter, Instant.parse("2018-05-07T00:00:00.000Z"));
assertThat(instance.convertDaysToWorkingDays(0)).isEqualTo(0);
assertThat(instance.convertDaysToWorkingDays(1)).isEqualTo(1);
@ -262,7 +262,7 @@ class WorkingDaysToDaysReportConverterTest {
throws InvalidArgumentException {
WorkingDaysToDaysReportConverter instance =
WorkingDaysToDaysReportConverter.initialize(
getLargeListOfColumnHeaders(), Instant.parse("2018-10-01T00:00:00.000Z"));
getLargeListOfColumnHeaders(), converter, Instant.parse("2018-10-01T00:00:00.000Z"));
assertThat(instance.convertDaysToWorkingDays(0)).isEqualTo(0);
assertThat(instance.convertDaysToWorkingDays(1)).isEqualTo(1);
@ -279,7 +279,7 @@ class WorkingDaysToDaysReportConverterTest {
throws InvalidArgumentException {
WorkingDaysToDaysReportConverter instance =
WorkingDaysToDaysReportConverter.initialize(
getLargeListOfColumnHeaders(), Instant.parse("2018-12-20T00:00:00.000Z"));
getLargeListOfColumnHeaders(), converter, Instant.parse("2018-12-20T00:00:00.000Z"));
assertThat(instance.convertDaysToWorkingDays(0)).isEqualTo(0);
assertThat(instance.convertDaysToWorkingDays(1)).isEqualTo(1);
@ -303,7 +303,7 @@ class WorkingDaysToDaysReportConverterTest {
throws InvalidArgumentException {
WorkingDaysToDaysReportConverter instance =
WorkingDaysToDaysReportConverter.initialize(
getLargeListOfColumnHeaders(), Instant.parse("2018-10-26T00:00:00.000Z"));
getLargeListOfColumnHeaders(), converter, Instant.parse("2018-10-26T00:00:00.000Z"));
assertThat(instance.convertDaysToWorkingDays(0)).isEqualTo(0);
assertThat(instance.convertDaysToWorkingDays(1)).isEqualTo(0);

View File

@ -6,7 +6,6 @@ import static org.mockito.Mockito.when;
import java.time.Instant;
import java.util.HashMap;
import java.util.Map;
import org.apache.ibatis.session.SqlSession;
import org.json.JSONArray;
import org.json.JSONObject;
import org.junit.jupiter.api.BeforeEach;
@ -15,9 +14,7 @@ import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import pro.taskana.TaskanaEngineConfiguration;
import pro.taskana.classification.api.models.Classification;
import pro.taskana.classification.internal.ClassificationQueryImpl;
import pro.taskana.classification.internal.ClassificationServiceImpl;
import pro.taskana.common.api.TaskanaEngine;
import pro.taskana.common.internal.InternalTaskanaEngine;
@ -38,8 +35,6 @@ class TaskServiceImplTest {
private TaskServiceImpl cut;
@Mock private TaskanaEngineConfiguration taskanaEngineConfigurationMock;
@Mock private InternalTaskanaEngine internalTaskanaEngineMock;
@Mock private TaskanaEngine taskanaEngineMock;
@ -48,25 +43,17 @@ class TaskServiceImplTest {
@Mock private TaskCommentMapper taskCommentMapperMock;
@Mock private ObjectReferenceMapper objectReferenceMapperMock;
@Mock private AttachmentMapper attachmentMapperMock;
@Mock private WorkbasketService workbasketServiceMock;
@Mock private ClassificationServiceImpl classificationServiceImplMock;
@Mock private AttachmentMapper attachmentMapperMock;
@Mock private ClassificationQueryImpl classificationQueryImplMock;
@Mock private SqlSession sqlSessionMock;
@BeforeEach
void setup() {
when(internalTaskanaEngineMock.getEngine()).thenReturn(taskanaEngineMock);
when(taskanaEngineMock.getWorkbasketService()).thenReturn(workbasketServiceMock);
when(taskanaEngineMock.getClassificationService()).thenReturn(classificationServiceImplMock);
when(taskanaEngineMock.getConfiguration()).thenReturn(taskanaEngineConfigurationMock);
when(taskanaEngineConfigurationMock.isGermanPublicHolidaysEnabled()).thenReturn(true);
cut =
new TaskServiceImpl(
internalTaskanaEngineMock, taskMapperMock, taskCommentMapperMock, attachmentMapperMock);