Task-1259: Refactoring of assembler classes
This commit is contained in:
parent
3dc5377c75
commit
0442dc54b4
|
@ -8,14 +8,13 @@ import java.time.Instant;
|
|||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.ZoneId;
|
||||
import java.util.ArrayList;
|
||||
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.Stream;
|
||||
import java.util.stream.LongStream.Builder;
|
||||
|
||||
import pro.taskana.common.api.CustomHoliday;
|
||||
import pro.taskana.common.api.exceptions.InvalidArgumentException;
|
||||
|
@ -37,6 +36,15 @@ public final class WorkingDaysToDaysConverter {
|
|||
private static boolean germanHolidaysEnabled;
|
||||
private static boolean corpusChristiEnabled; // Fronleichnam
|
||||
private static Set<CustomHoliday> customHolidays = new HashSet<>();
|
||||
private static Set<CustomHoliday> germanHolidays =
|
||||
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 Instant referenceDate;
|
||||
private LocalDate easterSunday;
|
||||
|
||||
|
@ -127,7 +135,7 @@ public final class WorkingDaysToDaysConverter {
|
|||
return instant.plus(Duration.ofDays(days));
|
||||
}
|
||||
|
||||
/** counts working days between two dates, inclusive for both margins. */
|
||||
/** 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;
|
||||
|
@ -155,28 +163,25 @@ public final class WorkingDaysToDaysConverter {
|
|||
}
|
||||
|
||||
public boolean isGermanHoliday(LocalDate date) {
|
||||
// Fix and movable holidays that are valid throughout Germany: New years day, Labour Day, Day of
|
||||
// German
|
||||
// Unity, Christmas,
|
||||
if (Stream.of(GermanFixHolidays.values()).anyMatch(day -> day.matches(date))) {
|
||||
if (germanHolidays.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);
|
||||
|
||||
List<Long> offSets =
|
||||
new ArrayList<>(
|
||||
Arrays.asList(
|
||||
OFFSET_GOOD_FRIDAY,
|
||||
OFFSET_EASTER_MONDAY,
|
||||
OFFSET_ASCENSION_DAY,
|
||||
OFFSET_WHIT_MONDAY));
|
||||
Builder builder =
|
||||
LongStream.builder()
|
||||
.add(OFFSET_GOOD_FRIDAY)
|
||||
.add(OFFSET_EASTER_MONDAY)
|
||||
.add(OFFSET_ASCENSION_DAY)
|
||||
.add(OFFSET_WHIT_MONDAY);
|
||||
|
||||
if (corpusChristiEnabled) {
|
||||
offSets.add(OFFSET_CORPUS_CHRISTI);
|
||||
builder.add(OFFSET_CORPUS_CHRISTI);
|
||||
}
|
||||
return offSets.contains(diffFromEasterSunday);
|
||||
|
||||
return builder.build().anyMatch(c -> c == diffFromEasterSunday);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -208,14 +213,6 @@ public final class WorkingDaysToDaysConverter {
|
|||
return LocalDate.of(year, 3, 22).plusDays((long) d + e);
|
||||
}
|
||||
|
||||
private int calculateDirection(long numberOfDays, ZeroDirection zeroDirection) {
|
||||
if (numberOfDays == 0) {
|
||||
return zeroDirection.getDirection();
|
||||
} else {
|
||||
return numberOfDays >= 0 ? 1 : -1;
|
||||
}
|
||||
}
|
||||
|
||||
void refreshReferenceDate(Instant newReferenceDate) {
|
||||
int yearOfReferenceDate =
|
||||
LocalDateTime.ofInstant(referenceDate, ZoneId.systemDefault()).getYear();
|
||||
|
@ -227,14 +224,21 @@ public final class WorkingDaysToDaysConverter {
|
|||
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{"
|
||||
+ "dateCreated="
|
||||
return "WorkingDaysToDaysConverter [referenceDate="
|
||||
+ referenceDate
|
||||
+ ", easterSunday="
|
||||
+ easterSunday
|
||||
+ '}';
|
||||
+ "]";
|
||||
}
|
||||
|
||||
private enum ZeroDirection {
|
||||
|
@ -251,25 +255,4 @@ public final class WorkingDaysToDaysConverter {
|
|||
return direction;
|
||||
}
|
||||
}
|
||||
|
||||
/** Enumeration of German holidays. */
|
||||
private enum GermanFixHolidays {
|
||||
NEWYEAR(1, 1),
|
||||
LABOURDAY(5, 1),
|
||||
GERMANUNITY(10, 3),
|
||||
CHRISTMAS1(12, 25),
|
||||
CHRISTMAS2(12, 26);
|
||||
|
||||
private final int month;
|
||||
private final int day;
|
||||
|
||||
GermanFixHolidays(int month, int day) {
|
||||
this.month = month;
|
||||
this.day = day;
|
||||
}
|
||||
|
||||
public boolean matches(LocalDate date) {
|
||||
return date.getDayOfMonth() == day && date.getMonthValue() == month;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,13 +20,13 @@ INSERT INTO WORKBASKET VALUES ('WBI:100000000000000000000000000000000014', 'USER
|
|||
INSERT INTO WORKBASKET VALUES ('WBI:100000000000000000000000000000000015', 'USER_3_2' , RELATIVE_DATE(0) , RELATIVE_DATE(0) , 'PPK User 2 KSC 1 Domain B', 'DOMAIN_B', 'PERSONAL', 'PPK User 1 KSC 1 Domain B' , 'owner0815' , 'ABCABC' , 'cust2' , 'cust3' , 'cust4' , 'orgl1' , 'orgl2' , 'orgl3' , 'orgl4' , false );
|
||||
|
||||
-- Workbaskets for sorting test
|
||||
INSERT INTO WORKBASKET VALUES ('WBI:000000000000000000000000000000000900', 'sort001' , RELATIVE_DATE(0) , RELATIVE_DATE(0) , 'basxet0' , 'DOM_XY' , 'TOPIC' , 'Lorem ipsum dolor sit amet.', 'Max' , '' , '' , '' , '' , '' , '' , '' , '' , false );
|
||||
INSERT INTO WORKBASKET VALUES ('WBI:000000000000000000000000000000000901', 'Sort002' , RELATIVE_DATE(0) , RELATIVE_DATE(0) , 'Basxet1' , 'DOM_XY' , 'TOPIC' , 'Lorem ipsum dolor sit amet.', 'Max' , '' , '' , '' , '' , '' , '' , '' , '' , false );
|
||||
INSERT INTO WORKBASKET VALUES ('WBI:000000000000000000000000000000000902', 'sOrt003' , RELATIVE_DATE(0) , RELATIVE_DATE(0) , 'bAsxet2' , 'DOM_XY' , 'TOPIC' , 'Lorem ipsum dolor sit amet.', 'Max' , '' , '' , '' , '' , '' , '' , '' , '' , false );
|
||||
INSERT INTO WORKBASKET VALUES ('WBI:000000000000000000000000000000000903', 'soRt004' , RELATIVE_DATE(0) , RELATIVE_DATE(0) , 'baSxet3' , 'DOM_XY' , 'TOPIC' , 'Lorem ipsum dolor sit amet.', 'Max' , '' , '' , '' , '' , '' , '' , '' , '' , false );
|
||||
INSERT INTO WORKBASKET VALUES ('WBI:000000000000000000000000000000000904', 'sorT005' , RELATIVE_DATE(0) , RELATIVE_DATE(0) , 'basXet4' , 'DOM_XY' , 'TOPIC' , 'Lorem ipsum dolor sit amet.', 'Max' , '' , '' , '' , '' , '' , '' , '' , '' , false );
|
||||
INSERT INTO WORKBASKET VALUES ('WBI:000000000000000000000000000000000905', 'Sort006' , RELATIVE_DATE(0) , RELATIVE_DATE(0) , 'basxEt5' , 'DOM_XY' , 'TOPIC' , 'Lorem ipsum dolor sit amet.', 'Max' , '' , '' , '' , '' , '' , '' , '' , '' , false );
|
||||
INSERT INTO WORKBASKET VALUES ('WBI:000000000000000000000000000000000906', 'SOrt007' , RELATIVE_DATE(0) , RELATIVE_DATE(0) , 'basxeT6' , 'DOM_XY' , 'TOPIC' , 'Lorem ipsum dolor sit amet.', 'Max' , '' , '' , '' , '' , '' , '' , '' , '' , false );
|
||||
INSERT INTO WORKBASKET VALUES ('WBI:000000000000000000000000000000000907', 'SoRt008' , RELATIVE_DATE(0) , RELATIVE_DATE(0) , 'BAsxet7' , 'DOM_XY' , 'TOPIC' , 'Lorem ipsum dolor sit amet.', 'Max' , '' , '' , '' , '' , '' , '' , '' , '' , false );
|
||||
INSERT INTO WORKBASKET VALUES ('WBI:000000000000000000000000000000000908', 'SorT009' , RELATIVE_DATE(0) , RELATIVE_DATE(0) , 'BaSxet8' , 'DOM_XY' , 'TOPIC' , 'Lorem ipsum dolor sit amet.', 'Max' , '' , '' , '' , '' , '' , '' , '' , '' , false );
|
||||
INSERT INTO WORKBASKET VALUES ('WBI:000000000000000000000000000000000909', 'Sort010' , RELATIVE_DATE(0) , RELATIVE_DATE(0) , 'BasXet9' , 'DOM_XY' , 'TOPIC' , 'Lorem ipsum dolor sit amet.', 'Max' , '' , '' , '' , '' , '' , '' , '' , '' , false );
|
||||
INSERT INTO WORKBASKET VALUES ('WBI:000000000000000000000000000000000900', 'sort001' , RELATIVE_DATE(0) , RELATIVE_DATE(0) , 'basxet0' , 'DOMAIN_A' , 'TOPIC' , 'Lorem ipsum dolor sit amet.', 'Max' , '' , '' , '' , '' , '' , '' , '' , '' , false );
|
||||
INSERT INTO WORKBASKET VALUES ('WBI:000000000000000000000000000000000901', 'Sort002' , RELATIVE_DATE(0) , RELATIVE_DATE(0) , 'Basxet1' , 'DOMAIN_A' , 'TOPIC' , 'Lorem ipsum dolor sit amet.', 'Max' , '' , '' , '' , '' , '' , '' , '' , '' , false );
|
||||
INSERT INTO WORKBASKET VALUES ('WBI:000000000000000000000000000000000902', 'sOrt003' , RELATIVE_DATE(0) , RELATIVE_DATE(0) , 'bAsxet2' , 'DOMAIN_A' , 'TOPIC' , 'Lorem ipsum dolor sit amet.', 'Max' , '' , '' , '' , '' , '' , '' , '' , '' , false );
|
||||
INSERT INTO WORKBASKET VALUES ('WBI:000000000000000000000000000000000903', 'soRt004' , RELATIVE_DATE(0) , RELATIVE_DATE(0) , 'baSxet3' , 'DOMAIN_A' , 'TOPIC' , 'Lorem ipsum dolor sit amet.', 'Max' , '' , '' , '' , '' , '' , '' , '' , '' , false );
|
||||
INSERT INTO WORKBASKET VALUES ('WBI:000000000000000000000000000000000904', 'sorT005' , RELATIVE_DATE(0) , RELATIVE_DATE(0) , 'basXet4' , 'DOMAIN_A' , 'TOPIC' , 'Lorem ipsum dolor sit amet.', 'Max' , '' , '' , '' , '' , '' , '' , '' , '' , false );
|
||||
INSERT INTO WORKBASKET VALUES ('WBI:000000000000000000000000000000000905', 'Sort006' , RELATIVE_DATE(0) , RELATIVE_DATE(0) , 'basxEt5' , 'DOMAIN_A' , 'TOPIC' , 'Lorem ipsum dolor sit amet.', 'Max' , '' , '' , '' , '' , '' , '' , '' , '' , false );
|
||||
INSERT INTO WORKBASKET VALUES ('WBI:000000000000000000000000000000000906', 'SOrt007' , RELATIVE_DATE(0) , RELATIVE_DATE(0) , 'basxeT6' , 'DOMAIN_A' , 'TOPIC' , 'Lorem ipsum dolor sit amet.', 'Max' , '' , '' , '' , '' , '' , '' , '' , '' , false );
|
||||
INSERT INTO WORKBASKET VALUES ('WBI:000000000000000000000000000000000907', 'SoRt008' , RELATIVE_DATE(0) , RELATIVE_DATE(0) , 'BAsxet7' , 'DOMAIN_A' , 'TOPIC' , 'Lorem ipsum dolor sit amet.', 'Max' , '' , '' , '' , '' , '' , '' , '' , '' , false );
|
||||
INSERT INTO WORKBASKET VALUES ('WBI:000000000000000000000000000000000908', 'SorT009' , RELATIVE_DATE(0) , RELATIVE_DATE(0) , 'BaSxet8' , 'DOMAIN_A' , 'TOPIC' , 'Lorem ipsum dolor sit amet.', 'Max' , '' , '' , '' , '' , '' , '' , '' , '' , false );
|
||||
INSERT INTO WORKBASKET VALUES ('WBI:000000000000000000000000000000000909', 'Sort010' , RELATIVE_DATE(0) , RELATIVE_DATE(0) , 'BasXet9' , 'DOMAIN_A' , 'TOPIC' , 'Lorem ipsum dolor sit amet.', 'Max' , '' , '' , '' , '' , '' , '' , '' , '' , false );
|
||||
|
|
|
@ -18,13 +18,13 @@ INSERT INTO WORKBASKET VALUES ('WBI:100000000000000000000000000000000014', 'USER
|
|||
INSERT INTO WORKBASKET VALUES ('WBI:100000000000000000000000000000000015', 'USER_3_2', RELATIVE_DATE(0) , RELATIVE_DATE(0) , 'PPK User 2 KSC 1 Domain B', 'DOMAIN_B', 'PERSONAL', 'PPK User 1 KSC 1 Domain B', 'owner0815', 'ABCABC', 'cust2', 'cust3', 'cust4', 'orgl1', 'orgl2', 'orgl3', 'orgl4', FALSE);
|
||||
|
||||
-- Workbaskets for sorting test
|
||||
INSERT INTO WORKBASKET VALUES ('WBI:000000000000000000000000000000000900', 'sort001', RELATIVE_DATE(0) , RELATIVE_DATE(0) , 'basxet0', 'DOM_XY', 'TOPIC', 'Lorem ipsum dolor sit amet.', 'Max', '', '', '', '', '', '', '', '', FALSE);
|
||||
INSERT INTO WORKBASKET VALUES ('WBI:000000000000000000000000000000000901', 'Sort002', RELATIVE_DATE(0) , RELATIVE_DATE(0) , 'Basxet1', 'DOM_XY', 'TOPIC', 'Lorem ipsum dolor sit amet.', 'Max', '', '', '', '', '', '', '', '', FALSE);
|
||||
INSERT INTO WORKBASKET VALUES ('WBI:000000000000000000000000000000000902', 'sOrt003', RELATIVE_DATE(0) , RELATIVE_DATE(0) , 'bAsxet2', 'DOM_XY', 'TOPIC', 'Lorem ipsum dolor sit amet.', 'Max', '', '', '', '', '', '', '', '', FALSE);
|
||||
INSERT INTO WORKBASKET VALUES ('WBI:000000000000000000000000000000000903', 'soRt004', RELATIVE_DATE(0) , RELATIVE_DATE(0) , 'baSxet3', 'DOM_XY', 'TOPIC', 'Lorem ipsum dolor sit amet.', 'Max', '', '', '', '', '', '', '', '', FALSE);
|
||||
INSERT INTO WORKBASKET VALUES ('WBI:000000000000000000000000000000000904', 'sorT005', RELATIVE_DATE(0) , RELATIVE_DATE(0) , 'basXet4', 'DOM_XY', 'TOPIC', 'Lorem ipsum dolor sit amet.', 'Max', '', '', '', '', '', '', '', '', FALSE);
|
||||
INSERT INTO WORKBASKET VALUES ('WBI:000000000000000000000000000000000905', 'Sort006', RELATIVE_DATE(0) , RELATIVE_DATE(0) , 'basxEt5', 'DOM_XY', 'TOPIC', 'Lorem ipsum dolor sit amet.', 'Max', '', '', '', '', '', '', '', '', FALSE);
|
||||
INSERT INTO WORKBASKET VALUES ('WBI:000000000000000000000000000000000906', 'SOrt007', RELATIVE_DATE(0) , RELATIVE_DATE(0) , 'basxeT6', 'DOM_XY', 'TOPIC', 'Lorem ipsum dolor sit amet.', 'Max', '', '', '', '', '', '', '', '', FALSE);
|
||||
INSERT INTO WORKBASKET VALUES ('WBI:000000000000000000000000000000000907', 'SoRt008', RELATIVE_DATE(0) , RELATIVE_DATE(0) , 'BAsxet7', 'DOM_XY', 'TOPIC', 'Lorem ipsum dolor sit amet.', 'Max', '', '', '', '', '', '', '', '', FALSE);
|
||||
INSERT INTO WORKBASKET VALUES ('WBI:000000000000000000000000000000000908', 'SorT009', RELATIVE_DATE(0) , RELATIVE_DATE(0) , 'BaSxet8', 'DOM_XY', 'TOPIC', 'Lorem ipsum dolor sit amet.', 'Max', '', '', '', '', '', '', '', '', FALSE);
|
||||
INSERT INTO WORKBASKET VALUES ('WBI:000000000000000000000000000000000909', 'Sort010', RELATIVE_DATE(0) , RELATIVE_DATE(0) , 'BasXet9', 'DOM_XY', 'TOPIC', 'Lorem ipsum dolor sit amet.', 'Max', '', '', '', '', '', '', '', '', FALSE);
|
||||
INSERT INTO WORKBASKET VALUES ('WBI:000000000000000000000000000000000900', 'sort001', RELATIVE_DATE(0) , RELATIVE_DATE(0) , 'basxet0', 'DOMAIN_A', 'TOPIC', 'Lorem ipsum dolor sit amet.', 'Max', '', '', '', '', '', '', '', '', FALSE);
|
||||
INSERT INTO WORKBASKET VALUES ('WBI:000000000000000000000000000000000901', 'Sort002', RELATIVE_DATE(0) , RELATIVE_DATE(0) , 'Basxet1', 'DOMAIN_A', 'TOPIC', 'Lorem ipsum dolor sit amet.', 'Max', '', '', '', '', '', '', '', '', FALSE);
|
||||
INSERT INTO WORKBASKET VALUES ('WBI:000000000000000000000000000000000902', 'sOrt003', RELATIVE_DATE(0) , RELATIVE_DATE(0) , 'bAsxet2', 'DOMAIN_A', 'TOPIC', 'Lorem ipsum dolor sit amet.', 'Max', '', '', '', '', '', '', '', '', FALSE);
|
||||
INSERT INTO WORKBASKET VALUES ('WBI:000000000000000000000000000000000903', 'soRt004', RELATIVE_DATE(0) , RELATIVE_DATE(0) , 'baSxet3', 'DOMAIN_A', 'TOPIC', 'Lorem ipsum dolor sit amet.', 'Max', '', '', '', '', '', '', '', '', FALSE);
|
||||
INSERT INTO WORKBASKET VALUES ('WBI:000000000000000000000000000000000904', 'sorT005', RELATIVE_DATE(0) , RELATIVE_DATE(0) , 'basXet4', 'DOMAIN_A', 'TOPIC', 'Lorem ipsum dolor sit amet.', 'Max', '', '', '', '', '', '', '', '', FALSE);
|
||||
INSERT INTO WORKBASKET VALUES ('WBI:000000000000000000000000000000000905', 'Sort006', RELATIVE_DATE(0) , RELATIVE_DATE(0) , 'basxEt5', 'DOMAIN_A', 'TOPIC', 'Lorem ipsum dolor sit amet.', 'Max', '', '', '', '', '', '', '', '', FALSE);
|
||||
INSERT INTO WORKBASKET VALUES ('WBI:000000000000000000000000000000000906', 'SOrt007', RELATIVE_DATE(0) , RELATIVE_DATE(0) , 'basxeT6', 'DOMAIN_A', 'TOPIC', 'Lorem ipsum dolor sit amet.', 'Max', '', '', '', '', '', '', '', '', FALSE);
|
||||
INSERT INTO WORKBASKET VALUES ('WBI:000000000000000000000000000000000907', 'SoRt008', RELATIVE_DATE(0) , RELATIVE_DATE(0) , 'BAsxet7', 'DOMAIN_A', 'TOPIC', 'Lorem ipsum dolor sit amet.', 'Max', '', '', '', '', '', '', '', '', FALSE);
|
||||
INSERT INTO WORKBASKET VALUES ('WBI:000000000000000000000000000000000908', 'SorT009', RELATIVE_DATE(0) , RELATIVE_DATE(0) , 'BaSxet8', 'DOMAIN_A', 'TOPIC', 'Lorem ipsum dolor sit amet.', 'Max', '', '', '', '', '', '', '', '', FALSE);
|
||||
INSERT INTO WORKBASKET VALUES ('WBI:000000000000000000000000000000000909', 'Sort010', RELATIVE_DATE(0) , RELATIVE_DATE(0) , 'BasXet9', 'DOMAIN_A', 'TOPIC', 'Lorem ipsum dolor sit amet.', 'Max', '', '', '', '', '', '', '', '', FALSE);
|
||||
|
|
|
@ -3,12 +3,16 @@ package pro.taskana;
|
|||
import com.fasterxml.jackson.databind.DeserializationFeature;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.SerializationFeature;
|
||||
import com.fasterxml.jackson.datatype.jdk8.Jdk8Module;
|
||||
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
|
||||
import com.fasterxml.jackson.module.paramnames.ParameterNamesModule;
|
||||
import java.util.Collections;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.hateoas.MediaTypes;
|
||||
import org.springframework.hateoas.mediatype.hal.Jackson2HalModule;
|
||||
import org.springframework.http.HttpEntity;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
@ -67,9 +71,13 @@ public class RestHelper {
|
|||
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
|
||||
mapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
|
||||
mapper.registerModule(new Jackson2HalModule());
|
||||
mapper
|
||||
.registerModule(new ParameterNamesModule())
|
||||
.registerModule(new Jdk8Module())
|
||||
.registerModule(new JavaTimeModule());
|
||||
|
||||
MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
|
||||
converter.setSupportedMediaTypes(MediaType.parseMediaTypes("application/hal+json"));
|
||||
converter.setSupportedMediaTypes(Collections.singletonList(MediaTypes.HAL_JSON));
|
||||
converter.setObjectMapper(mapper);
|
||||
|
||||
RestTemplate template = new RestTemplate();
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
package pro.taskana.jobs;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static pro.taskana.RestHelper.TEMPLATE;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
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 org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
@ -19,14 +19,12 @@ import org.springframework.http.HttpMethod;
|
|||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.test.context.ActiveProfiles;
|
||||
import org.springframework.test.context.junit.jupiter.SpringExtension;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
import pro.taskana.RestConfiguration;
|
||||
import pro.taskana.RestHelper;
|
||||
import pro.taskana.classification.api.models.Classification;
|
||||
import pro.taskana.classification.rest.assembler.ClassificationRepresentationModelAssembler;
|
||||
import pro.taskana.classification.rest.models.ClassificationRepresentationModel;
|
||||
import pro.taskana.common.api.exceptions.InvalidArgumentException;
|
||||
import pro.taskana.common.rest.Mapping;
|
||||
import pro.taskana.task.api.models.Task;
|
||||
import pro.taskana.task.rest.assembler.TaskRepresentationModelAssembler;
|
||||
|
@ -42,17 +40,25 @@ class AsyncUpdateJobIntTest {
|
|||
|
||||
private static final String CLASSIFICATION_ID = "CLI:100000000000000000000000000000000003";
|
||||
|
||||
@SuppressWarnings("checkstyle:DeclarationOrder")
|
||||
static RestTemplate template;
|
||||
private final ClassificationRepresentationModelAssembler
|
||||
classificationRepresentationModelAssembler;
|
||||
private final TaskRepresentationModelAssembler taskRepresentationModelAssembler;
|
||||
private final JobScheduler jobScheduler;
|
||||
private final RestHelper restHelper;
|
||||
private final ObjectMapper mapper;
|
||||
|
||||
@Autowired ClassificationRepresentationModelAssembler classificationRepresentationModelAssembler;
|
||||
@Autowired TaskRepresentationModelAssembler taskRepresentationModelAssembler;
|
||||
@Autowired JobScheduler jobScheduler;
|
||||
@Autowired RestHelper restHelper;
|
||||
|
||||
@BeforeAll
|
||||
static void init() {
|
||||
template = RestHelper.TEMPLATE;
|
||||
@Autowired
|
||||
AsyncUpdateJobIntTest(
|
||||
ClassificationRepresentationModelAssembler classificationRepresentationModelAssembler,
|
||||
TaskRepresentationModelAssembler taskRepresentationModelAssembler,
|
||||
JobScheduler jobScheduler,
|
||||
RestHelper restHelper,
|
||||
ObjectMapper mapper) {
|
||||
this.classificationRepresentationModelAssembler = classificationRepresentationModelAssembler;
|
||||
this.taskRepresentationModelAssembler = taskRepresentationModelAssembler;
|
||||
this.jobScheduler = jobScheduler;
|
||||
this.restHelper = restHelper;
|
||||
this.mapper = mapper;
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -60,10 +66,9 @@ class AsyncUpdateJobIntTest {
|
|||
|
||||
// 1st step: get old classification :
|
||||
final Instant before = Instant.now();
|
||||
final ObjectMapper mapper = new ObjectMapper();
|
||||
|
||||
ResponseEntity<ClassificationRepresentationModel> response =
|
||||
template.exchange(
|
||||
TEMPLATE.exchange(
|
||||
restHelper.toUrl(Mapping.URL_CLASSIFICATIONS_ID, CLASSIFICATION_ID),
|
||||
HttpMethod.GET,
|
||||
new HttpEntity<String>(restHelper.getHeaders()),
|
||||
|
@ -78,7 +83,7 @@ class AsyncUpdateJobIntTest {
|
|||
classification.setServiceLevel("P5D");
|
||||
classification.setPriority(1000);
|
||||
|
||||
template.put(
|
||||
TEMPLATE.put(
|
||||
restHelper.toUrl(Mapping.URL_CLASSIFICATIONS_ID, CLASSIFICATION_ID),
|
||||
new HttpEntity<>(mapper.writeValueAsString(classification), restHelper.getHeaders()));
|
||||
|
||||
|
@ -89,7 +94,7 @@ class AsyncUpdateJobIntTest {
|
|||
|
||||
// verify the classification modified timestamp is after 'before'
|
||||
ResponseEntity<ClassificationRepresentationModel> repeatedResponse =
|
||||
template.exchange(
|
||||
TEMPLATE.exchange(
|
||||
restHelper.toUrl(Mapping.URL_CLASSIFICATIONS_ID, CLASSIFICATION_ID),
|
||||
HttpMethod.GET,
|
||||
new HttpEntity<String>(restHelper.getHeaders()),
|
||||
|
@ -150,17 +155,17 @@ class AsyncUpdateJobIntTest {
|
|||
}
|
||||
}
|
||||
|
||||
private void verifyTaskIsModifiedAfterOrEquals(String taskId, Instant before)
|
||||
throws InvalidArgumentException {
|
||||
private void verifyTaskIsModifiedAfterOrEquals(String taskId, Instant before) {
|
||||
|
||||
ResponseEntity<TaskRepresentationModel> taskResponse =
|
||||
template.exchange(
|
||||
TEMPLATE.exchange(
|
||||
restHelper.toUrl(Mapping.URL_TASKS_ID, taskId),
|
||||
HttpMethod.GET,
|
||||
new HttpEntity<>(restHelper.getHeadersAdmin()),
|
||||
ParameterizedTypeReference.forType(TaskRepresentationModel.class));
|
||||
|
||||
TaskRepresentationModel taskRepresentationModel = taskResponse.getBody();
|
||||
assertThat(taskRepresentationModel).isNotNull();
|
||||
Task task = taskRepresentationModelAssembler.toEntityModel(taskRepresentationModel);
|
||||
|
||||
Instant modified = task.getModified();
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
package pro.taskana.classification.rest;
|
||||
|
||||
import static pro.taskana.common.internal.util.CheckedFunction.wrap;
|
||||
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import com.fasterxml.jackson.databind.DeserializationFeature;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
|
@ -13,6 +15,7 @@ import java.util.Set;
|
|||
import java.util.stream.Collectors;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.dao.DuplicateKeyException;
|
||||
import org.springframework.hateoas.config.EnableHypermediaSupport;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
|
@ -37,6 +40,7 @@ import pro.taskana.common.api.exceptions.DomainNotFoundException;
|
|||
import pro.taskana.common.api.exceptions.InvalidArgumentException;
|
||||
import pro.taskana.common.api.exceptions.NotAuthorizedException;
|
||||
import pro.taskana.common.rest.Mapping;
|
||||
import pro.taskana.common.rest.models.TaskanaPagedModel;
|
||||
|
||||
/** Controller for Importing / Exporting classifications. */
|
||||
@SuppressWarnings("unused")
|
||||
|
@ -47,37 +51,41 @@ public class ClassificationDefinitionController {
|
|||
private static final Logger LOGGER =
|
||||
LoggerFactory.getLogger(ClassificationDefinitionController.class);
|
||||
|
||||
private final ObjectMapper mapper;
|
||||
private final ClassificationService classificationService;
|
||||
|
||||
private final ClassificationRepresentationModelAssembler
|
||||
classificationRepresentationModelAssembler;
|
||||
|
||||
@Autowired
|
||||
ClassificationDefinitionController(
|
||||
ObjectMapper mapper,
|
||||
ClassificationService classificationService,
|
||||
ClassificationRepresentationModelAssembler classificationRepresentationModelAssembler) {
|
||||
this.mapper = mapper;
|
||||
this.classificationService = classificationService;
|
||||
this.classificationRepresentationModelAssembler = classificationRepresentationModelAssembler;
|
||||
}
|
||||
|
||||
@GetMapping(path = Mapping.URL_CLASSIFICATIONDEFINITION)
|
||||
@Transactional(readOnly = true, rollbackFor = Exception.class)
|
||||
public ResponseEntity<List<ClassificationRepresentationModel>> exportClassifications(
|
||||
public ResponseEntity<TaskanaPagedModel<ClassificationRepresentationModel>> exportClassifications(
|
||||
@RequestParam(required = false) String domain) throws ClassificationNotFoundException {
|
||||
LOGGER.debug("Entry to exportClassifications(domain= {})", domain);
|
||||
ClassificationQuery query = classificationService.createClassificationQuery();
|
||||
|
||||
List<ClassificationSummary> summaries =
|
||||
domain != null ? query.domainIn(domain).list() : query.list();
|
||||
List<ClassificationRepresentationModel> export = new ArrayList<>();
|
||||
|
||||
for (ClassificationSummary summary : summaries) {
|
||||
Classification classification =
|
||||
classificationService.getClassification(summary.getKey(), summary.getDomain());
|
||||
TaskanaPagedModel<ClassificationRepresentationModel> pageModel =
|
||||
summaries.stream()
|
||||
.map(ClassificationSummary::getId)
|
||||
.map(wrap(classificationService::getClassification))
|
||||
.collect(
|
||||
Collectors.collectingAndThen(
|
||||
Collectors.toList(), classificationRepresentationModelAssembler::toPageModel));
|
||||
|
||||
export.add(classificationRepresentationModelAssembler.toModel(classification));
|
||||
}
|
||||
|
||||
ResponseEntity<List<ClassificationRepresentationModel>> response = ResponseEntity.ok(export);
|
||||
ResponseEntity<TaskanaPagedModel<ClassificationRepresentationModel>> response =
|
||||
ResponseEntity.ok(pageModel);
|
||||
if (LOGGER.isDebugEnabled()) {
|
||||
LOGGER.debug("Exit from exportClassifications(), returning {}", response);
|
||||
}
|
||||
|
@ -93,13 +101,13 @@ public class ClassificationDefinitionController {
|
|||
DomainNotFoundException, IOException {
|
||||
LOGGER.debug("Entry to importClassifications()");
|
||||
Map<String, String> systemIds = getSystemIds();
|
||||
List<ClassificationRepresentationModel> classificationsResources =
|
||||
TaskanaPagedModel<ClassificationRepresentationModel> classificationsResources =
|
||||
extractClassificationResourcesFromFile(file);
|
||||
checkForDuplicates(classificationsResources);
|
||||
checkForDuplicates(classificationsResources.getContent());
|
||||
|
||||
Map<Classification, String> childrenInFile =
|
||||
mapChildrenToParentKeys(classificationsResources, systemIds);
|
||||
insertOrUpdateClassificationsWithoutParent(classificationsResources, systemIds);
|
||||
mapChildrenToParentKeys(classificationsResources.getContent(), systemIds);
|
||||
insertOrUpdateClassificationsWithoutParent(classificationsResources.getContent(), systemIds);
|
||||
updateParentChildrenRelations(childrenInFile);
|
||||
ResponseEntity<Void> response = ResponseEntity.noContent().build();
|
||||
LOGGER.debug("Exit from importClassifications(), returning {}", response);
|
||||
|
@ -112,15 +120,15 @@ public class ClassificationDefinitionController {
|
|||
Collectors.toMap(i -> i.getKey() + "|" + i.getDomain(), ClassificationSummary::getId));
|
||||
}
|
||||
|
||||
private List<ClassificationRepresentationModel> extractClassificationResourcesFromFile(
|
||||
MultipartFile file) throws IOException {
|
||||
ObjectMapper mapper = new ObjectMapper();
|
||||
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
|
||||
private TaskanaPagedModel<ClassificationRepresentationModel>
|
||||
extractClassificationResourcesFromFile(MultipartFile file) throws IOException {
|
||||
return mapper.readValue(
|
||||
file.getInputStream(), new TypeReference<List<ClassificationRepresentationModel>>() {});
|
||||
file.getInputStream(),
|
||||
new TypeReference<TaskanaPagedModel<ClassificationRepresentationModel>>() {});
|
||||
}
|
||||
|
||||
private void checkForDuplicates(List<ClassificationRepresentationModel> classificationList) {
|
||||
private void checkForDuplicates(
|
||||
Collection<ClassificationRepresentationModel> classificationList) {
|
||||
List<String> identifiers = new ArrayList<>();
|
||||
Set<String> duplicates = new HashSet<>();
|
||||
for (ClassificationRepresentationModel classification : classificationList) {
|
||||
|
@ -138,7 +146,7 @@ public class ClassificationDefinitionController {
|
|||
}
|
||||
|
||||
private Map<Classification, String> mapChildrenToParentKeys(
|
||||
List<ClassificationRepresentationModel> classificationRepresentationModels,
|
||||
Collection<ClassificationRepresentationModel> classificationRepresentationModels,
|
||||
Map<String, String> systemIds) {
|
||||
LOGGER.debug("Entry to mapChildrenToParentKeys()");
|
||||
Map<Classification, String> childrenInFile = new HashMap<>();
|
||||
|
@ -159,8 +167,9 @@ public class ClassificationDefinitionController {
|
|||
}
|
||||
|
||||
String parentKeyAndDomain = cl.getParentKey() + "|" + cl.getDomain();
|
||||
if ((!cl.getParentKey().isEmpty() && !cl.getParentKey().equals("") && (
|
||||
newKeysWithDomain.contains(parentKeyAndDomain)
|
||||
if ((!cl.getParentKey().isEmpty()
|
||||
&& !cl.getParentKey().equals("")
|
||||
&& (newKeysWithDomain.contains(parentKeyAndDomain)
|
||||
|| systemIds.containsKey(parentKeyAndDomain)))) {
|
||||
childrenInFile.put(
|
||||
classificationRepresentationModelAssembler.toEntityModel(cl), cl.getParentKey());
|
||||
|
@ -176,7 +185,7 @@ public class ClassificationDefinitionController {
|
|||
}
|
||||
|
||||
private void insertOrUpdateClassificationsWithoutParent(
|
||||
List<ClassificationRepresentationModel> classificationRepresentationModels,
|
||||
Collection<ClassificationRepresentationModel> classificationRepresentationModels,
|
||||
Map<String, String> systemIds)
|
||||
throws ClassificationNotFoundException, NotAuthorizedException, InvalidArgumentException,
|
||||
ClassificationAlreadyExistException, DomainNotFoundException, ConcurrencyException {
|
||||
|
@ -197,8 +206,8 @@ public class ClassificationDefinitionController {
|
|||
updateExistingClassification(classificationRepresentationModel, systemId);
|
||||
} else {
|
||||
classificationService.createClassification(
|
||||
classificationRepresentationModelAssembler
|
||||
.toEntityModel(classificationRepresentationModel));
|
||||
classificationRepresentationModelAssembler.toEntityModel(
|
||||
classificationRepresentationModel));
|
||||
}
|
||||
}
|
||||
LOGGER.debug("Exit from insertOrUpdateClassificationsWithoutParent()");
|
||||
|
|
|
@ -2,10 +2,8 @@ package pro.taskana.classification.rest.assembler;
|
|||
|
||||
import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.methodOn;
|
||||
|
||||
import java.time.Instant;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.hateoas.server.RepresentationModelAssembler;
|
||||
import org.springframework.hateoas.server.mvc.WebMvcLinkBuilder;
|
||||
import org.springframework.lang.NonNull;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
@ -17,6 +15,8 @@ import pro.taskana.classification.internal.models.ClassificationImpl;
|
|||
import pro.taskana.classification.rest.ClassificationController;
|
||||
import pro.taskana.classification.rest.models.ClassificationRepresentationModel;
|
||||
import pro.taskana.common.api.exceptions.SystemException;
|
||||
import pro.taskana.common.rest.assembler.TaskanaPagingAssembler;
|
||||
import pro.taskana.common.rest.models.TaskanaPagedModelKeys;
|
||||
|
||||
/**
|
||||
* Transforms {@link Classification} to its resource counterpart {@link
|
||||
|
@ -24,13 +24,12 @@ import pro.taskana.common.api.exceptions.SystemException;
|
|||
*/
|
||||
@Component
|
||||
public class ClassificationRepresentationModelAssembler
|
||||
implements RepresentationModelAssembler<Classification, ClassificationRepresentationModel> {
|
||||
implements TaskanaPagingAssembler<Classification, ClassificationRepresentationModel> {
|
||||
|
||||
final ClassificationService classificationService;
|
||||
|
||||
@Autowired
|
||||
public ClassificationRepresentationModelAssembler(
|
||||
ClassificationService classificationService) {
|
||||
public ClassificationRepresentationModelAssembler(ClassificationService classificationService) {
|
||||
this.classificationService = classificationService;
|
||||
}
|
||||
|
||||
|
@ -42,7 +41,8 @@ public class ClassificationRepresentationModelAssembler
|
|||
try {
|
||||
resource.add(
|
||||
WebMvcLinkBuilder.linkTo(
|
||||
methodOn(ClassificationController.class).getClassification(classification.getId()))
|
||||
methodOn(ClassificationController.class)
|
||||
.getClassification(classification.getId()))
|
||||
.withSelfRel());
|
||||
} catch (ClassificationNotFoundException e) {
|
||||
throw new SystemException("caught unexpected Exception.", e.getCause());
|
||||
|
@ -50,6 +50,11 @@ public class ClassificationRepresentationModelAssembler
|
|||
return resource;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TaskanaPagedModelKeys getProperty() {
|
||||
return TaskanaPagedModelKeys.CLASSIFICATIONS;
|
||||
}
|
||||
|
||||
public Classification toEntityModel(
|
||||
ClassificationRepresentationModel classificationRepresentationModel) {
|
||||
ClassificationImpl classification =
|
||||
|
@ -61,12 +66,8 @@ public class ClassificationRepresentationModelAssembler
|
|||
BeanUtils.copyProperties(classificationRepresentationModel, classification);
|
||||
|
||||
classification.setId(classificationRepresentationModel.getClassificationId());
|
||||
if (classificationRepresentationModel.getCreated() != null) {
|
||||
classification.setCreated(Instant.parse(classificationRepresentationModel.getCreated()));
|
||||
}
|
||||
if (classificationRepresentationModel.getModified() != null) {
|
||||
classification.setModified(Instant.parse(classificationRepresentationModel.getModified()));
|
||||
}
|
||||
classification.setCreated(classificationRepresentationModel.getCreated());
|
||||
classification.setModified(classificationRepresentationModel.getModified());
|
||||
return classification;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,12 +2,9 @@ package pro.taskana.classification.rest.assembler;
|
|||
|
||||
import static pro.taskana.common.rest.models.TaskanaPagedModelKeys.CLASSIFICATIONS;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.hateoas.PagedModel.PageMetadata;
|
||||
import org.springframework.hateoas.server.RepresentationModelAssembler;
|
||||
import org.springframework.lang.NonNull;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
|
@ -16,16 +13,16 @@ import pro.taskana.classification.api.models.ClassificationSummary;
|
|||
import pro.taskana.classification.internal.models.ClassificationImpl;
|
||||
import pro.taskana.classification.rest.models.ClassificationSummaryRepresentationModel;
|
||||
import pro.taskana.common.rest.Mapping;
|
||||
import pro.taskana.common.rest.assembler.TaskanaPagingAssembler;
|
||||
import pro.taskana.common.rest.models.TaskanaPagedModel;
|
||||
import pro.taskana.common.rest.models.TaskanaPagedModelKeys;
|
||||
import pro.taskana.resource.rest.PageLinks;
|
||||
|
||||
/**
|
||||
* EntityModel assembler for {@link ClassificationSummaryRepresentationModel}.
|
||||
*/
|
||||
/** EntityModel assembler for {@link ClassificationSummaryRepresentationModel}. */
|
||||
@Component
|
||||
public class ClassificationSummaryRepresentationModelAssembler
|
||||
implements
|
||||
RepresentationModelAssembler<ClassificationSummary, ClassificationSummaryRepresentationModel> {
|
||||
implements TaskanaPagingAssembler<
|
||||
ClassificationSummary, ClassificationSummaryRepresentationModel> {
|
||||
|
||||
private final ClassificationService classificationService;
|
||||
|
||||
|
@ -51,15 +48,16 @@ public class ClassificationSummaryRepresentationModelAssembler
|
|||
BeanUtils.copyProperties(resource, classification);
|
||||
return classification.asSummary();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public TaskanaPagedModelKeys getProperty() {
|
||||
return CLASSIFICATIONS;
|
||||
}
|
||||
|
||||
@PageLinks(Mapping.URL_CLASSIFICATIONS)
|
||||
@Override
|
||||
public TaskanaPagedModel<ClassificationSummaryRepresentationModel> toPageModel(
|
||||
List<ClassificationSummary> classificationSummaries, PageMetadata pageMetadata) {
|
||||
return classificationSummaries.stream()
|
||||
.map(this::toModel)
|
||||
.collect(
|
||||
Collectors.collectingAndThen(
|
||||
Collectors.toList(),
|
||||
list -> new TaskanaPagedModel<>(CLASSIFICATIONS, list, pageMetadata)));
|
||||
Iterable<? extends ClassificationSummary> entities, PageMetadata pageMetadata) {
|
||||
return TaskanaPagingAssembler.super.toPageModel(entities, pageMetadata);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,28 +1,25 @@
|
|||
package pro.taskana.classification.rest.models;
|
||||
|
||||
import java.time.Instant;
|
||||
|
||||
import pro.taskana.classification.api.models.Classification;
|
||||
|
||||
/**
|
||||
* EntityModel class for {@link Classification}.
|
||||
*/
|
||||
public class ClassificationRepresentationModel
|
||||
extends ClassificationSummaryRepresentationModel {
|
||||
/** EntityModel class for {@link Classification}. */
|
||||
public class ClassificationRepresentationModel extends ClassificationSummaryRepresentationModel {
|
||||
|
||||
private Boolean isValidInDomain;
|
||||
private String created; // ISO-8601
|
||||
private String modified; // ISO-8601
|
||||
|
||||
private Instant created; // ISO-8601
|
||||
private Instant modified; // ISO-8601
|
||||
private String description;
|
||||
|
||||
public ClassificationRepresentationModel() {
|
||||
}
|
||||
public ClassificationRepresentationModel() {}
|
||||
|
||||
public ClassificationRepresentationModel(Classification classification) {
|
||||
super(classification);
|
||||
this.isValidInDomain = classification.getIsValidInDomain();
|
||||
this.created =
|
||||
classification.getCreated() != null ? classification.getCreated().toString() : null;
|
||||
this.modified =
|
||||
classification.getModified() != null ? classification.getModified().toString() : null;
|
||||
this.created = classification.getCreated();
|
||||
this.modified = classification.getModified();
|
||||
this.description = classification.getDescription();
|
||||
}
|
||||
|
||||
|
@ -30,23 +27,23 @@ public class ClassificationRepresentationModel
|
|||
return isValidInDomain;
|
||||
}
|
||||
|
||||
public void setIsValidInDomain(Boolean validInDomain) {
|
||||
isValidInDomain = validInDomain;
|
||||
public void setIsValidInDomain(Boolean isValidInDomain) {
|
||||
this.isValidInDomain = isValidInDomain;
|
||||
}
|
||||
|
||||
public String getCreated() {
|
||||
public Instant getCreated() {
|
||||
return created;
|
||||
}
|
||||
|
||||
public void setCreated(String created) {
|
||||
public void setCreated(Instant created) {
|
||||
this.created = created;
|
||||
}
|
||||
|
||||
public String getModified() {
|
||||
public Instant getModified() {
|
||||
return modified;
|
||||
}
|
||||
|
||||
public void setModified(String modified) {
|
||||
public void setModified(Instant modified) {
|
||||
this.modified = modified;
|
||||
}
|
||||
|
||||
|
@ -57,55 +54,4 @@ public class ClassificationRepresentationModel
|
|||
public void setDescription(String description) {
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ClassificationResource [classificationId="
|
||||
+ classificationId
|
||||
+ ", key="
|
||||
+ key
|
||||
+ ", parentId="
|
||||
+ parentId
|
||||
+ ", parentKey="
|
||||
+ parentKey
|
||||
+ ", category="
|
||||
+ category
|
||||
+ ", type="
|
||||
+ type
|
||||
+ ", domain="
|
||||
+ domain
|
||||
+ ", isValidInDomain="
|
||||
+ isValidInDomain
|
||||
+ ", created="
|
||||
+ created
|
||||
+ ", modified="
|
||||
+ modified
|
||||
+ ", name="
|
||||
+ name
|
||||
+ ", description="
|
||||
+ description
|
||||
+ ", priority="
|
||||
+ priority
|
||||
+ ", serviceLevel="
|
||||
+ serviceLevel
|
||||
+ ", applicationEntryPoint="
|
||||
+ applicationEntryPoint
|
||||
+ ", custom1="
|
||||
+ custom1
|
||||
+ ", custom2="
|
||||
+ custom2
|
||||
+ ", custom3="
|
||||
+ custom3
|
||||
+ ", custom4="
|
||||
+ custom4
|
||||
+ ", custom5="
|
||||
+ custom5
|
||||
+ ", custom6="
|
||||
+ custom6
|
||||
+ ", custom7="
|
||||
+ custom7
|
||||
+ ", custom8="
|
||||
+ custom8
|
||||
+ "]";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
package pro.taskana.common.rest.assembler;
|
||||
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.StreamSupport;
|
||||
import org.springframework.hateoas.PagedModel.PageMetadata;
|
||||
import org.springframework.hateoas.RepresentationModel;
|
||||
import org.springframework.hateoas.server.RepresentationModelAssembler;
|
||||
|
||||
import pro.taskana.common.rest.models.TaskanaPagedModel;
|
||||
import pro.taskana.common.rest.models.TaskanaPagedModelKeys;
|
||||
|
||||
public interface TaskanaPagingAssembler<T, D extends RepresentationModel<? super D>>
|
||||
extends RepresentationModelAssembler<T, D> {
|
||||
|
||||
TaskanaPagedModelKeys getProperty();
|
||||
|
||||
default TaskanaPagedModel<D> toPageModel(
|
||||
Iterable<? extends T> entities, PageMetadata pageMetadata) {
|
||||
return StreamSupport.stream(entities.spliterator(), false)
|
||||
.map(this::toModel)
|
||||
.collect(
|
||||
Collectors.collectingAndThen(
|
||||
Collectors.toList(), l -> new TaskanaPagedModel<>(getProperty(), l, pageMetadata)));
|
||||
}
|
||||
|
||||
default TaskanaPagedModel<D> toPageModel(Iterable<? extends T> entities) {
|
||||
return toPageModel(entities, null);
|
||||
}
|
||||
}
|
|
@ -17,26 +17,23 @@ import org.springframework.hateoas.RepresentationModel;
|
|||
*
|
||||
* @param <T> The class of the paginated content
|
||||
*/
|
||||
public class TaskanaPagedModel<T extends RepresentationModel<T>>
|
||||
public class TaskanaPagedModel<T extends RepresentationModel<? super T>>
|
||||
extends RepresentationModel<TaskanaPagedModel<T>> {
|
||||
|
||||
@JsonIgnore
|
||||
private TaskanaPagedModelKeys key;
|
||||
@JsonIgnore
|
||||
private Collection<? extends T> content;
|
||||
@JsonIgnore private TaskanaPagedModelKeys key;
|
||||
@JsonIgnore private Collection<? extends T> content;
|
||||
|
||||
@JsonProperty(value = "page", access = Access.WRITE_ONLY)
|
||||
private PageMetadata metadata;
|
||||
|
||||
@SuppressWarnings("unused") // needed for jackson
|
||||
private TaskanaPagedModel() {
|
||||
}
|
||||
private TaskanaPagedModel() {}
|
||||
|
||||
/**
|
||||
* Creates a new {@link TaskanaPagedModel} from the given content.
|
||||
*
|
||||
* @param property property which will be used for serialization.
|
||||
* @param content must not be {@literal null}.
|
||||
* @param content must not be {@literal null}.
|
||||
* @param metadata the metadata. Can be null. If null, no metadata will be serialized.
|
||||
*/
|
||||
public TaskanaPagedModel(
|
||||
|
@ -46,6 +43,10 @@ public class TaskanaPagedModel<T extends RepresentationModel<T>>
|
|||
this.key = property;
|
||||
}
|
||||
|
||||
public TaskanaPagedModel(TaskanaPagedModelKeys property, Collection<? extends T> content) {
|
||||
this(property, content, null);
|
||||
}
|
||||
|
||||
public Collection<T> getContent() {
|
||||
return Collections.unmodifiableCollection(content);
|
||||
}
|
||||
|
@ -54,6 +55,10 @@ public class TaskanaPagedModel<T extends RepresentationModel<T>>
|
|||
return metadata;
|
||||
}
|
||||
|
||||
public TaskanaPagedModelKeys getKey() {
|
||||
return key;
|
||||
}
|
||||
|
||||
@JsonAnySetter
|
||||
private void deserialize(String propertyName, Collection<T> content) {
|
||||
TaskanaPagedModelKeys.getEnumFromPropertyName(propertyName)
|
||||
|
|
|
@ -12,7 +12,8 @@ public enum TaskanaPagedModelKeys {
|
|||
DISTRIBUTION_TARGETS("distributionTargets"),
|
||||
TASKS("tasks"),
|
||||
TASK_COMMENTS("taskComments"),
|
||||
WORKBASKETS("workbaskets");
|
||||
WORKBASKETS("workbaskets"),
|
||||
WORKBASKET_DEFINITIONS("workbasketDefinitions");
|
||||
|
||||
private static final Map<String, TaskanaPagedModelKeys> PROPERTY_MAP =
|
||||
Arrays.stream(TaskanaPagedModelKeys.values())
|
||||
|
|
|
@ -1,23 +1,60 @@
|
|||
package pro.taskana.task.rest.assembler;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.hateoas.server.RepresentationModelAssembler;
|
||||
import org.springframework.lang.NonNull;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import pro.taskana.classification.rest.assembler.ClassificationSummaryRepresentationModelAssembler;
|
||||
import pro.taskana.task.api.TaskService;
|
||||
import pro.taskana.task.api.models.AttachmentSummary;
|
||||
import pro.taskana.task.internal.models.AttachmentImpl;
|
||||
import pro.taskana.task.rest.models.AttachmentSummaryRepresentationModel;
|
||||
|
||||
/**
|
||||
* EntityModel assembler for {@link AttachmentSummaryRepresentationModel}.
|
||||
*/
|
||||
/** EntityModel assembler for {@link AttachmentSummaryRepresentationModel}. */
|
||||
@Component
|
||||
public class AttachmentSummaryRepresentationModelAssembler implements
|
||||
RepresentationModelAssembler<AttachmentSummary, AttachmentSummaryRepresentationModel> {
|
||||
public class AttachmentSummaryRepresentationModelAssembler
|
||||
implements RepresentationModelAssembler<
|
||||
AttachmentSummary, AttachmentSummaryRepresentationModel> {
|
||||
|
||||
private final TaskService taskService;
|
||||
private final ClassificationSummaryRepresentationModelAssembler classificationSummaryAssembler;
|
||||
|
||||
@Autowired
|
||||
public AttachmentSummaryRepresentationModelAssembler(
|
||||
TaskService taskService,
|
||||
ClassificationSummaryRepresentationModelAssembler classificationSummaryAssembler) {
|
||||
this.taskService = taskService;
|
||||
this.classificationSummaryAssembler = classificationSummaryAssembler;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public AttachmentSummaryRepresentationModel toModel(
|
||||
@NonNull AttachmentSummary attachmentSummary) {
|
||||
return new AttachmentSummaryRepresentationModel(attachmentSummary);
|
||||
public AttachmentSummaryRepresentationModel toModel(@NonNull AttachmentSummary summary) {
|
||||
AttachmentSummaryRepresentationModel repModel = new AttachmentSummaryRepresentationModel();
|
||||
repModel.setAttachmentId(summary.getId());
|
||||
repModel.setTaskId(summary.getTaskId());
|
||||
repModel.setCreated(summary.getCreated());
|
||||
repModel.setModified(summary.getModified());
|
||||
repModel.setReceived(summary.getReceived());
|
||||
repModel.setClassificationSummary(
|
||||
classificationSummaryAssembler.toModel(summary.getClassificationSummary()));
|
||||
repModel.setObjectReference(summary.getObjectReference());
|
||||
repModel.setChannel(summary.getChannel());
|
||||
return repModel;
|
||||
}
|
||||
|
||||
public AttachmentSummary toEntityModel(AttachmentSummaryRepresentationModel repModel) {
|
||||
AttachmentImpl attachment = (AttachmentImpl) taskService.newAttachment();
|
||||
attachment.setId(repModel.getAttachmentId());
|
||||
attachment.setTaskId(repModel.getTaskId());
|
||||
attachment.setCreated(repModel.getCreated());
|
||||
attachment.setModified(repModel.getModified());
|
||||
attachment.setReceived(repModel.getReceived());
|
||||
attachment.setClassificationSummary(
|
||||
classificationSummaryAssembler.toEntityModel(repModel.getClassificationSummary()));
|
||||
attachment.setObjectReference(repModel.getObjectReference());
|
||||
attachment.setChannel(repModel.getChannel());
|
||||
return attachment;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,12 +3,11 @@ package pro.taskana.task.rest.assembler;
|
|||
import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.linkTo;
|
||||
import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.methodOn;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.hateoas.server.mvc.RepresentationModelAssemblerSupport;
|
||||
import org.springframework.hateoas.server.RepresentationModelAssembler;
|
||||
import org.springframework.lang.NonNull;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
|
@ -30,7 +29,7 @@ import pro.taskana.workbasket.rest.assembler.WorkbasketSummaryRepresentationMode
|
|||
*/
|
||||
@Component
|
||||
public class TaskRepresentationModelAssembler
|
||||
extends RepresentationModelAssemblerSupport<Task, TaskRepresentationModel> {
|
||||
implements RepresentationModelAssembler<Task, TaskRepresentationModel> {
|
||||
|
||||
private final TaskService taskService;
|
||||
|
||||
|
@ -47,7 +46,6 @@ public class TaskRepresentationModelAssembler
|
|||
ClassificationSummaryRepresentationModelAssembler classificationAssembler,
|
||||
WorkbasketSummaryRepresentationModelAssembler workbasketSummaryRepresentationModelAssembler,
|
||||
AttachmentRepresentationModelAssembler attachmentAssembler) {
|
||||
super(TaskController.class, TaskRepresentationModel.class);
|
||||
this.taskService = taskService;
|
||||
this.classificationAssembler = classificationAssembler;
|
||||
this.workbasketSummaryRepresentationModelAssembler
|
||||
|
@ -68,8 +66,7 @@ public class TaskRepresentationModelAssembler
|
|||
return resource;
|
||||
}
|
||||
|
||||
public Task toEntityModel(TaskRepresentationModel resource) throws InvalidArgumentException {
|
||||
validateTaskResource(resource);
|
||||
public Task toEntityModel(TaskRepresentationModel resource) {
|
||||
TaskImpl task =
|
||||
(TaskImpl)
|
||||
taskService.newTask(
|
||||
|
@ -77,24 +74,7 @@ public class TaskRepresentationModelAssembler
|
|||
task.setId(resource.getTaskId());
|
||||
task.setExternalId(resource.getExternalId());
|
||||
BeanUtils.copyProperties(resource, task);
|
||||
if (resource.getCreated() != null) {
|
||||
task.setCreated(Instant.parse(resource.getCreated()));
|
||||
}
|
||||
if (resource.getModified() != null) {
|
||||
task.setModified(Instant.parse(resource.getModified()));
|
||||
}
|
||||
if (resource.getClaimed() != null) {
|
||||
task.setClaimed(Instant.parse(resource.getClaimed()));
|
||||
}
|
||||
if (resource.getCompleted() != null) {
|
||||
task.setCompleted(Instant.parse(resource.getCompleted()));
|
||||
}
|
||||
if (resource.getDue() != null) {
|
||||
task.setDue(Instant.parse(resource.getDue()));
|
||||
}
|
||||
if (resource.getPlanned() != null) {
|
||||
task.setPlanned(Instant.parse(resource.getPlanned()));
|
||||
}
|
||||
|
||||
task.setClassificationSummary(
|
||||
classificationAssembler.toEntityModel(
|
||||
resource.getClassificationSummary()));
|
||||
|
@ -113,20 +93,4 @@ public class TaskRepresentationModelAssembler
|
|||
|
||||
return task;
|
||||
}
|
||||
|
||||
private void validateTaskResource(TaskRepresentationModel resource)
|
||||
throws InvalidArgumentException {
|
||||
if (resource.getWorkbasketSummary() == null
|
||||
|| resource.getWorkbasketSummary().getWorkbasketId() == null
|
||||
|| resource.getWorkbasketSummary().getWorkbasketId().isEmpty()) {
|
||||
throw new InvalidArgumentException(
|
||||
"TaskResource must have a workbasket summary with a valid workbasketId.");
|
||||
}
|
||||
if (resource.getClassificationSummary() == null
|
||||
|| resource.getClassificationSummary().getKey() == null
|
||||
|| resource.getClassificationSummary().getKey().isEmpty()) {
|
||||
throw new InvalidArgumentException(
|
||||
"TaskResource must have a classification summary with a valid classification key.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,42 +1,39 @@
|
|||
package pro.taskana.task.rest.models;
|
||||
|
||||
import java.time.Instant;
|
||||
import org.springframework.hateoas.RepresentationModel;
|
||||
|
||||
import pro.taskana.classification.rest.models.ClassificationSummaryRepresentationModel;
|
||||
import pro.taskana.task.api.models.AttachmentSummary;
|
||||
import pro.taskana.task.api.models.ObjectReference;
|
||||
|
||||
/**
|
||||
* EntityModel class for {@link AttachmentSummary}.
|
||||
*/
|
||||
/** EntityModel class for {@link AttachmentSummary}. */
|
||||
public class AttachmentSummaryRepresentationModel
|
||||
extends RepresentationModel<AttachmentSummaryRepresentationModel> {
|
||||
|
||||
protected String attachmentId;
|
||||
protected String taskId;
|
||||
protected String created;
|
||||
protected String modified;
|
||||
protected Instant created;
|
||||
protected Instant modified;
|
||||
protected Instant received;
|
||||
protected ClassificationSummaryRepresentationModel classificationSummary;
|
||||
protected ObjectReference objectReference;
|
||||
protected String channel;
|
||||
protected String received;
|
||||
|
||||
AttachmentSummaryRepresentationModel() {
|
||||
}
|
||||
// TODO: remove this constructor
|
||||
public AttachmentSummaryRepresentationModel() {}
|
||||
|
||||
// TODO: remove this constructor
|
||||
public AttachmentSummaryRepresentationModel(AttachmentSummary attachmentSummary) {
|
||||
this.attachmentId = attachmentSummary.getId();
|
||||
this.taskId = attachmentSummary.getTaskId();
|
||||
this.created =
|
||||
attachmentSummary.getCreated() != null ? attachmentSummary.getCreated().toString() : null;
|
||||
this.modified =
|
||||
attachmentSummary.getModified() != null ? attachmentSummary.getModified().toString() : null;
|
||||
this.created = attachmentSummary.getCreated();
|
||||
this.modified = attachmentSummary.getModified();
|
||||
this.received = attachmentSummary.getReceived();
|
||||
this.classificationSummary =
|
||||
new ClassificationSummaryRepresentationModel(attachmentSummary.getClassificationSummary());
|
||||
this.objectReference = attachmentSummary.getObjectReference();
|
||||
this.channel = attachmentSummary.getChannel();
|
||||
this.received =
|
||||
attachmentSummary.getReceived() != null ? attachmentSummary.getReceived().toString() : null;
|
||||
}
|
||||
|
||||
public String getAttachmentId() {
|
||||
|
@ -55,22 +52,30 @@ public class AttachmentSummaryRepresentationModel
|
|||
this.taskId = taskId;
|
||||
}
|
||||
|
||||
public String getCreated() {
|
||||
public Instant getCreated() {
|
||||
return created;
|
||||
}
|
||||
|
||||
public void setCreated(String created) {
|
||||
public void setCreated(Instant created) {
|
||||
this.created = created;
|
||||
}
|
||||
|
||||
public String getModified() {
|
||||
public Instant getModified() {
|
||||
return modified;
|
||||
}
|
||||
|
||||
public void setModified(String modified) {
|
||||
public void setModified(Instant modified) {
|
||||
this.modified = modified;
|
||||
}
|
||||
|
||||
public Instant getReceived() {
|
||||
return received;
|
||||
}
|
||||
|
||||
public void setReceived(Instant received) {
|
||||
this.received = received;
|
||||
}
|
||||
|
||||
public ClassificationSummaryRepresentationModel getClassificationSummary() {
|
||||
return classificationSummary;
|
||||
}
|
||||
|
@ -95,34 +100,4 @@ public class AttachmentSummaryRepresentationModel
|
|||
public void setChannel(String channel) {
|
||||
this.channel = channel;
|
||||
}
|
||||
|
||||
public String getReceived() {
|
||||
return received;
|
||||
}
|
||||
|
||||
public void setReceived(String received) {
|
||||
this.received = received;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "AttachmentSummaryResource ["
|
||||
+ "attachmentId= "
|
||||
+ this.attachmentId
|
||||
+ "taskId= "
|
||||
+ this.taskId
|
||||
+ "created= "
|
||||
+ this.created
|
||||
+ "modified= "
|
||||
+ this.modified
|
||||
+ "classificationSummaryResource= "
|
||||
+ this.classificationSummary
|
||||
+ "objectReference= "
|
||||
+ this.objectReference
|
||||
+ "channel= "
|
||||
+ this.channel
|
||||
+ "received= "
|
||||
+ this.received
|
||||
+ "]";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package pro.taskana.task.rest.models;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
@ -21,12 +22,12 @@ public class TaskSummaryRepresentationModel
|
|||
|
||||
protected String taskId;
|
||||
protected String externalId;
|
||||
protected String created; // ISO-8601
|
||||
protected String claimed; // ISO-8601
|
||||
protected String completed; // ISO-8601
|
||||
protected String modified; // ISO-8601
|
||||
protected String planned; // ISO-8601
|
||||
protected String due; // ISO-8601
|
||||
protected Instant created; // ISO-8601
|
||||
protected Instant claimed; // ISO-8601
|
||||
protected Instant completed; // ISO-8601
|
||||
protected Instant modified; // ISO-8601
|
||||
protected Instant planned; // ISO-8601
|
||||
protected Instant due; // ISO-8601
|
||||
protected String name;
|
||||
protected String creator;
|
||||
protected String note;
|
||||
|
@ -66,12 +67,12 @@ public class TaskSummaryRepresentationModel
|
|||
public TaskSummaryRepresentationModel(TaskSummary taskSummary) throws InvalidArgumentException {
|
||||
this.taskId = taskSummary.getId();
|
||||
this.externalId = taskSummary.getExternalId();
|
||||
created = taskSummary.getCreated() != null ? taskSummary.getCreated().toString() : null;
|
||||
claimed = taskSummary.getClaimed() != null ? taskSummary.getClaimed().toString() : null;
|
||||
completed = taskSummary.getCompleted() != null ? taskSummary.getCompleted().toString() : null;
|
||||
modified = taskSummary.getModified() != null ? taskSummary.getModified().toString() : null;
|
||||
planned = taskSummary.getPlanned() != null ? taskSummary.getPlanned().toString() : null;
|
||||
due = taskSummary.getDue() != null ? taskSummary.getDue().toString() : null;
|
||||
created = taskSummary.getCreated();
|
||||
claimed = taskSummary.getClaimed();
|
||||
completed = taskSummary.getCompleted();
|
||||
modified = taskSummary.getModified();
|
||||
planned = taskSummary.getPlanned();
|
||||
due = taskSummary.getDue();
|
||||
this.name = taskSummary.getName();
|
||||
this.creator = taskSummary.getCreator();
|
||||
this.note = taskSummary.getNote();
|
||||
|
@ -126,51 +127,51 @@ public class TaskSummaryRepresentationModel
|
|||
this.externalId = externalId;
|
||||
}
|
||||
|
||||
public String getCreated() {
|
||||
public Instant getCreated() {
|
||||
return created;
|
||||
}
|
||||
|
||||
public void setCreated(String created) {
|
||||
public void setCreated(Instant created) {
|
||||
this.created = created;
|
||||
}
|
||||
|
||||
public String getClaimed() {
|
||||
public Instant getClaimed() {
|
||||
return claimed;
|
||||
}
|
||||
|
||||
public void setClaimed(String claimed) {
|
||||
public void setClaimed(Instant claimed) {
|
||||
this.claimed = claimed;
|
||||
}
|
||||
|
||||
public String getCompleted() {
|
||||
public Instant getCompleted() {
|
||||
return completed;
|
||||
}
|
||||
|
||||
public void setCompleted(String completed) {
|
||||
public void setCompleted(Instant completed) {
|
||||
this.completed = completed;
|
||||
}
|
||||
|
||||
public String getModified() {
|
||||
public Instant getModified() {
|
||||
return modified;
|
||||
}
|
||||
|
||||
public void setModified(String modified) {
|
||||
public void setModified(Instant modified) {
|
||||
this.modified = modified;
|
||||
}
|
||||
|
||||
public String getPlanned() {
|
||||
public Instant getPlanned() {
|
||||
return planned;
|
||||
}
|
||||
|
||||
public void setPlanned(String planned) {
|
||||
public void setPlanned(Instant planned) {
|
||||
this.planned = planned;
|
||||
}
|
||||
|
||||
public String getDue() {
|
||||
public Instant getDue() {
|
||||
return due;
|
||||
}
|
||||
|
||||
public void setDue(String due) {
|
||||
public void setDue(Instant due) {
|
||||
this.due = due;
|
||||
}
|
||||
|
||||
|
|
|
@ -42,7 +42,6 @@ import pro.taskana.workbasket.api.exceptions.WorkbasketNotFoundException;
|
|||
import pro.taskana.workbasket.api.models.Workbasket;
|
||||
import pro.taskana.workbasket.api.models.WorkbasketAccessItem;
|
||||
import pro.taskana.workbasket.api.models.WorkbasketSummary;
|
||||
import pro.taskana.workbasket.rest.assembler.DistributionTargetRepresentationModelAssembler;
|
||||
import pro.taskana.workbasket.rest.assembler.WorkbasketAccessItemRepresentationModelAssembler;
|
||||
import pro.taskana.workbasket.rest.assembler.WorkbasketRepresentationModelAssembler;
|
||||
import pro.taskana.workbasket.rest.assembler.WorkbasketSummaryRepresentationModelAssembler;
|
||||
|
@ -80,8 +79,7 @@ public class WorkbasketController extends AbstractPagingController {
|
|||
private final WorkbasketSummaryRepresentationModelAssembler
|
||||
workbasketSummaryRepresentationModelAssembler;
|
||||
|
||||
private final DistributionTargetRepresentationModelAssembler
|
||||
distributionTargetRepresentationModelAssembler;
|
||||
|
||||
|
||||
private final WorkbasketAccessItemRepresentationModelAssembler
|
||||
workbasketAccessItemRepresentationModelAssembler;
|
||||
|
@ -90,15 +88,13 @@ public class WorkbasketController extends AbstractPagingController {
|
|||
WorkbasketService workbasketService,
|
||||
WorkbasketRepresentationModelAssembler workbasketRepresentationModelAssembler,
|
||||
WorkbasketSummaryRepresentationModelAssembler workbasketSummaryRepresentationModelAssembler,
|
||||
DistributionTargetRepresentationModelAssembler distributionTargetRepresentationModelAssembler,
|
||||
WorkbasketAccessItemRepresentationModelAssembler
|
||||
workbasketAccessItemRepresentationModelAssembler) {
|
||||
this.workbasketService = workbasketService;
|
||||
this.workbasketRepresentationModelAssembler = workbasketRepresentationModelAssembler;
|
||||
this.workbasketSummaryRepresentationModelAssembler =
|
||||
workbasketSummaryRepresentationModelAssembler;
|
||||
this.distributionTargetRepresentationModelAssembler =
|
||||
distributionTargetRepresentationModelAssembler;
|
||||
|
||||
this.workbasketAccessItemRepresentationModelAssembler =
|
||||
workbasketAccessItemRepresentationModelAssembler;
|
||||
}
|
||||
|
@ -236,7 +232,7 @@ public class WorkbasketController extends AbstractPagingController {
|
|||
workbasketService.getWorkbasketAccessItems(workbasketId);
|
||||
result =
|
||||
ResponseEntity.ok(
|
||||
workbasketAccessItemRepresentationModelAssembler.toPageModel(
|
||||
workbasketAccessItemRepresentationModelAssembler.toPageModelForSingleWorkbasket(
|
||||
workbasketId, accessItems, null));
|
||||
if (LOGGER.isDebugEnabled()) {
|
||||
LOGGER.debug("Exit from getWorkbasketAccessItems(), returning {}", result);
|
||||
|
@ -268,7 +264,7 @@ public class WorkbasketController extends AbstractPagingController {
|
|||
|
||||
ResponseEntity<TaskanaPagedModel<WorkbasketAccessItemRepresentationModel>> response =
|
||||
ResponseEntity.ok(
|
||||
workbasketAccessItemRepresentationModelAssembler.toPageModel(
|
||||
workbasketAccessItemRepresentationModelAssembler.toPageModelForSingleWorkbasket(
|
||||
workbasketId, updatedWbAccessItems, null));
|
||||
if (LOGGER.isDebugEnabled()) {
|
||||
LOGGER.debug("Exit from setWorkbasketAccessItems(), returning {}", response);
|
||||
|
@ -287,7 +283,8 @@ public class WorkbasketController extends AbstractPagingController {
|
|||
List<WorkbasketSummary> distributionTargets =
|
||||
workbasketService.getDistributionTargets(workbasketId);
|
||||
TaskanaPagedModel<WorkbasketSummaryRepresentationModel> distributionTargetListResource =
|
||||
distributionTargetRepresentationModelAssembler.toPageModel(distributionTargets, null);
|
||||
workbasketSummaryRepresentationModelAssembler
|
||||
.toDistributionTargetPageModel(distributionTargets, null);
|
||||
ResponseEntity<TaskanaPagedModel<WorkbasketSummaryRepresentationModel>> result =
|
||||
ResponseEntity.ok(distributionTargetListResource);
|
||||
if (LOGGER.isDebugEnabled()) {
|
||||
|
@ -317,7 +314,8 @@ public class WorkbasketController extends AbstractPagingController {
|
|||
workbasketService.getDistributionTargets(sourceWorkbasketId);
|
||||
ResponseEntity<TaskanaPagedModel<WorkbasketSummaryRepresentationModel>> response =
|
||||
ResponseEntity.ok(
|
||||
distributionTargetRepresentationModelAssembler.toPageModel(distributionTargets, null));
|
||||
workbasketSummaryRepresentationModelAssembler
|
||||
.toDistributionTargetPageModel(distributionTargets, null));
|
||||
if (LOGGER.isDebugEnabled()) {
|
||||
LOGGER.debug("Exit from getTasksStatusReport(), returning {}", response);
|
||||
}
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
package pro.taskana.workbasket.rest;
|
||||
|
||||
import static pro.taskana.common.internal.util.CheckedFunction.wrap;
|
||||
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import com.fasterxml.jackson.databind.DeserializationFeature;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.SerializationFeature;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
|
@ -14,6 +15,7 @@ import java.util.Set;
|
|||
import java.util.stream.Collectors;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.dao.DuplicateKeyException;
|
||||
import org.springframework.hateoas.config.EnableHypermediaSupport;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
|
@ -29,6 +31,7 @@ import pro.taskana.common.api.exceptions.DomainNotFoundException;
|
|||
import pro.taskana.common.api.exceptions.InvalidArgumentException;
|
||||
import pro.taskana.common.api.exceptions.NotAuthorizedException;
|
||||
import pro.taskana.common.rest.Mapping;
|
||||
import pro.taskana.common.rest.models.TaskanaPagedModel;
|
||||
import pro.taskana.workbasket.api.WorkbasketQuery;
|
||||
import pro.taskana.workbasket.api.WorkbasketService;
|
||||
import pro.taskana.workbasket.api.exceptions.InvalidWorkbasketException;
|
||||
|
@ -53,33 +56,38 @@ public class WorkbasketDefinitionController {
|
|||
LoggerFactory.getLogger(WorkbasketDefinitionController.class);
|
||||
|
||||
private final WorkbasketService workbasketService;
|
||||
|
||||
private final WorkbasketDefinitionRepresentationModelAssembler workbasketDefinitionAssembler;
|
||||
private final ObjectMapper mapper;
|
||||
|
||||
@Autowired
|
||||
WorkbasketDefinitionController(
|
||||
WorkbasketService workbasketService,
|
||||
WorkbasketDefinitionRepresentationModelAssembler workbasketDefinitionAssembler) {
|
||||
WorkbasketDefinitionRepresentationModelAssembler workbasketDefinitionAssembler,
|
||||
ObjectMapper mapper) {
|
||||
this.workbasketService = workbasketService;
|
||||
this.workbasketDefinitionAssembler = workbasketDefinitionAssembler;
|
||||
this.mapper = mapper;
|
||||
}
|
||||
|
||||
@GetMapping(path = Mapping.URL_WORKBASKETDEFIITIONS)
|
||||
@Transactional(readOnly = true, rollbackFor = Exception.class)
|
||||
public ResponseEntity<List<WorkbasketDefinitionRepresentationModel>> exportWorkbaskets(
|
||||
@RequestParam(required = false) String domain)
|
||||
throws NotAuthorizedException, WorkbasketNotFoundException {
|
||||
public ResponseEntity<TaskanaPagedModel<WorkbasketDefinitionRepresentationModel>>
|
||||
exportWorkbaskets(@RequestParam(required = false) String domain) {
|
||||
LOGGER.debug("Entry to exportWorkbaskets(domain= {})", domain);
|
||||
WorkbasketQuery workbasketQuery = workbasketService.createWorkbasketQuery();
|
||||
List<WorkbasketSummary> workbasketSummaryList =
|
||||
domain != null ? workbasketQuery.domainIn(domain).list() : workbasketQuery.list();
|
||||
List<WorkbasketDefinitionRepresentationModel> basketExports = new ArrayList<>();
|
||||
for (WorkbasketSummary summary : workbasketSummaryList) {
|
||||
Workbasket workbasket = workbasketService.getWorkbasket(summary.getId());
|
||||
basketExports.add(workbasketDefinitionAssembler.toModel(workbasket));
|
||||
}
|
||||
|
||||
ResponseEntity<List<WorkbasketDefinitionRepresentationModel>> response =
|
||||
ResponseEntity.ok(basketExports);
|
||||
TaskanaPagedModel<WorkbasketDefinitionRepresentationModel> pageModel =
|
||||
workbasketSummaryList.stream()
|
||||
.map(WorkbasketSummary::getId)
|
||||
.map(wrap(workbasketService::getWorkbasket))
|
||||
.collect(
|
||||
Collectors.collectingAndThen(
|
||||
Collectors.toList(), workbasketDefinitionAssembler::toPageModel));
|
||||
|
||||
ResponseEntity<TaskanaPagedModel<WorkbasketDefinitionRepresentationModel>> response =
|
||||
ResponseEntity.ok(pageModel);
|
||||
if (LOGGER.isDebugEnabled()) {
|
||||
LOGGER.debug("Exit from exportWorkbaskets(), returning {}", response);
|
||||
}
|
||||
|
@ -118,29 +126,26 @@ public class WorkbasketDefinitionController {
|
|||
InvalidArgumentException, WorkbasketAccessItemAlreadyExistException,
|
||||
ConcurrencyException {
|
||||
LOGGER.debug("Entry to importWorkbaskets()");
|
||||
ObjectMapper mapper = new ObjectMapper();
|
||||
mapper.enable(SerializationFeature.INDENT_OUTPUT);
|
||||
mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
|
||||
List<WorkbasketDefinitionRepresentationModel> definitions =
|
||||
TaskanaPagedModel<WorkbasketDefinitionRepresentationModel> definitions =
|
||||
mapper.readValue(
|
||||
file.getInputStream(),
|
||||
new TypeReference<List<WorkbasketDefinitionRepresentationModel>>() {});
|
||||
new TypeReference<TaskanaPagedModel<WorkbasketDefinitionRepresentationModel>>() {});
|
||||
|
||||
// key: logical ID
|
||||
// value: system ID (in database)
|
||||
Map<String, String> systemIds =
|
||||
workbasketService.createWorkbasketQuery().list().stream()
|
||||
.collect(Collectors.toMap(this::logicalId, WorkbasketSummary::getId));
|
||||
checkForDuplicates(definitions);
|
||||
checkForDuplicates(definitions.getContent());
|
||||
|
||||
// key: old system ID
|
||||
// value: system ID
|
||||
Map<String, String> idConversion = new HashMap<>();
|
||||
|
||||
// STEP 1: update or create workbaskets from the import
|
||||
for (WorkbasketDefinitionRepresentationModel definition : definitions) {
|
||||
Workbasket importedWb = workbasketDefinitionAssembler
|
||||
.toEntityModel(definition.getWorkbasket());
|
||||
for (WorkbasketDefinitionRepresentationModel definition : definitions.getContent()) {
|
||||
Workbasket importedWb =
|
||||
workbasketDefinitionAssembler.toEntityModel(definition.getWorkbasket());
|
||||
String newId;
|
||||
WorkbasketImpl wbWithoutId = (WorkbasketImpl) removeId(importedWb);
|
||||
if (systemIds.containsKey(logicalId(importedWb))) {
|
||||
|
@ -160,8 +165,9 @@ public class WorkbasketDefinitionController {
|
|||
boolean authenticated =
|
||||
definition.getAuthorizations().stream()
|
||||
.anyMatch(
|
||||
access -> (access.getWorkbasketId().equals(importedWb.getId()))
|
||||
&& (access.getWorkbasketKey().equals(importedWb.getKey())));
|
||||
access ->
|
||||
(access.getWorkbasketId().equals(importedWb.getId()))
|
||||
&& (access.getWorkbasketKey().equals(importedWb.getKey())));
|
||||
if (!authenticated && !definition.getAuthorizations().isEmpty()) {
|
||||
throw new InvalidWorkbasketException(
|
||||
"The given Authentications for Workbasket "
|
||||
|
@ -181,7 +187,7 @@ public class WorkbasketDefinitionController {
|
|||
|
||||
// STEP 2: update distribution targets
|
||||
// This can not be done in step 1 because the system IDs are only known after step 1
|
||||
for (WorkbasketDefinitionRepresentationModel definition : definitions) {
|
||||
for (WorkbasketDefinitionRepresentationModel definition : definitions.getContent()) {
|
||||
List<String> distributionTargets = new ArrayList<>();
|
||||
for (String oldId : definition.getDistributionTargets()) {
|
||||
if (idConversion.containsKey(oldId)) {
|
||||
|
@ -211,7 +217,7 @@ public class WorkbasketDefinitionController {
|
|||
return workbasketDefinitionAssembler.toEntityModel(wbRes);
|
||||
}
|
||||
|
||||
private void checkForDuplicates(List<WorkbasketDefinitionRepresentationModel> definitions) {
|
||||
private void checkForDuplicates(Collection<WorkbasketDefinitionRepresentationModel> definitions) {
|
||||
List<String> identifiers = new ArrayList<>();
|
||||
Set<String> duplicates = new HashSet<>();
|
||||
for (WorkbasketDefinitionRepresentationModel definition : definitions) {
|
||||
|
|
|
@ -1,21 +1 @@
|
|||
package pro.taskana.workbasket.rest.assembler;
|
||||
|
||||
import static pro.taskana.common.rest.models.TaskanaPagedModelKeys.DISTRIBUTION_TARGETS;
|
||||
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import pro.taskana.common.rest.models.TaskanaPagedModelKeys;
|
||||
|
||||
/**
|
||||
* Transforms WorkbasketSummary to its resource counterpart DistributionTargerResource and vice
|
||||
* versa.
|
||||
*/
|
||||
@Component
|
||||
public class DistributionTargetRepresentationModelAssembler
|
||||
extends WorkbasketSummaryRepresentationModelAssembler {
|
||||
|
||||
@Override
|
||||
protected TaskanaPagedModelKeys getKey() {
|
||||
return DISTRIBUTION_TARGETS;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -58,7 +58,7 @@ public class WorkbasketAccessItemRepresentationModelAssembler
|
|||
return wbAccItemModel;
|
||||
}
|
||||
|
||||
public TaskanaPagedModel<WorkbasketAccessItemRepresentationModel> toPageModel(
|
||||
public TaskanaPagedModel<WorkbasketAccessItemRepresentationModel> toPageModelForSingleWorkbasket(
|
||||
String workbasketId,
|
||||
List<WorkbasketAccessItem> workbasketAccessItems,
|
||||
PageMetadata pageMetadata)
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
package pro.taskana.workbasket.rest.assembler;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
@ -11,6 +10,9 @@ import org.springframework.lang.NonNull;
|
|||
import org.springframework.stereotype.Component;
|
||||
|
||||
import pro.taskana.common.api.exceptions.NotAuthorizedException;
|
||||
import pro.taskana.common.api.exceptions.SystemException;
|
||||
import pro.taskana.common.rest.assembler.TaskanaPagingAssembler;
|
||||
import pro.taskana.common.rest.models.TaskanaPagedModelKeys;
|
||||
import pro.taskana.workbasket.api.WorkbasketService;
|
||||
import pro.taskana.workbasket.api.exceptions.WorkbasketNotFoundException;
|
||||
import pro.taskana.workbasket.api.models.Workbasket;
|
||||
|
@ -27,41 +29,40 @@ import pro.taskana.workbasket.rest.models.WorkbasketRepresentationModelWithoutLi
|
|||
* all additional information about that workbasket.
|
||||
*/
|
||||
@Component
|
||||
public class WorkbasketDefinitionRepresentationModelAssembler {
|
||||
public class WorkbasketDefinitionRepresentationModelAssembler
|
||||
implements TaskanaPagingAssembler<Workbasket, WorkbasketDefinitionRepresentationModel> {
|
||||
|
||||
private final WorkbasketService workbasketService;
|
||||
|
||||
@Autowired
|
||||
public WorkbasketDefinitionRepresentationModelAssembler(
|
||||
WorkbasketService workbasketService) {
|
||||
public WorkbasketDefinitionRepresentationModelAssembler(WorkbasketService workbasketService) {
|
||||
this.workbasketService = workbasketService;
|
||||
}
|
||||
|
||||
/**
|
||||
* maps the distro targets to their id to remove overhead.
|
||||
*
|
||||
* @param workbasket {@link Workbasket} which will be converted
|
||||
* @return a {@link WorkbasketDefinitionRepresentationModel}, containing the {@code basket}, its
|
||||
* distribution targets and its authorizations
|
||||
* @throws NotAuthorizedException if the user is not authorized
|
||||
* @throws WorkbasketNotFoundException if {@code basket} is an unknown workbasket
|
||||
*/
|
||||
@NonNull
|
||||
public WorkbasketDefinitionRepresentationModel toModel(Workbasket workbasket)
|
||||
throws NotAuthorizedException, WorkbasketNotFoundException {
|
||||
public WorkbasketDefinitionRepresentationModel toModel(@NonNull Workbasket workbasket) {
|
||||
|
||||
WorkbasketRepresentationModelWithoutLinks basket =
|
||||
new WorkbasketRepresentationModelWithoutLinks(workbasket);
|
||||
|
||||
List<WorkbasketAccessItemImpl> authorizations = new ArrayList<>();
|
||||
for (WorkbasketAccessItem accessItem :
|
||||
workbasketService.getWorkbasketAccessItems(basket.getWorkbasketId())) {
|
||||
authorizations.add((WorkbasketAccessItemImpl) accessItem);
|
||||
try {
|
||||
for (WorkbasketAccessItem accessItem :
|
||||
workbasketService.getWorkbasketAccessItems(basket.getWorkbasketId())) {
|
||||
authorizations.add((WorkbasketAccessItemImpl) accessItem);
|
||||
}
|
||||
} catch (NotAuthorizedException e) {
|
||||
throw new SystemException("Caught Exception", e);
|
||||
}
|
||||
Set<String> distroTargets = null;
|
||||
try {
|
||||
distroTargets =
|
||||
workbasketService.getDistributionTargets(workbasket.getId()).stream()
|
||||
.map(WorkbasketSummary::getId)
|
||||
.collect(Collectors.toSet());
|
||||
} catch (NotAuthorizedException | WorkbasketNotFoundException e) {
|
||||
throw new SystemException("Caught Exception", e);
|
||||
}
|
||||
Set<String> distroTargets =
|
||||
workbasketService.getDistributionTargets(workbasket.getId()).stream()
|
||||
.map(WorkbasketSummary::getId)
|
||||
.collect(Collectors.toSet());
|
||||
return new WorkbasketDefinitionRepresentationModel(basket, distroTargets, authorizations);
|
||||
}
|
||||
|
||||
|
@ -72,12 +73,13 @@ public class WorkbasketDefinitionRepresentationModelAssembler {
|
|||
BeanUtils.copyProperties(wbResource, workbasket);
|
||||
|
||||
workbasket.setId(wbResource.getWorkbasketId());
|
||||
if (wbResource.getModified() != null) {
|
||||
workbasket.setModified(Instant.parse(wbResource.getModified()));
|
||||
}
|
||||
if (wbResource.getCreated() != null) {
|
||||
workbasket.setCreated(Instant.parse(wbResource.getCreated()));
|
||||
}
|
||||
workbasket.setModified(wbResource.getModified());
|
||||
workbasket.setCreated(wbResource.getCreated());
|
||||
return workbasket;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TaskanaPagedModelKeys getProperty() {
|
||||
return TaskanaPagedModelKeys.WORKBASKET_DEFINITIONS;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,7 +3,6 @@ package pro.taskana.workbasket.rest.assembler;
|
|||
import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.linkTo;
|
||||
import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.methodOn;
|
||||
|
||||
import java.time.Instant;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.hateoas.server.RepresentationModelAssembler;
|
||||
|
@ -32,8 +31,7 @@ public class WorkbasketRepresentationModelAssembler
|
|||
private final WorkbasketService workbasketService;
|
||||
|
||||
@Autowired
|
||||
public WorkbasketRepresentationModelAssembler(
|
||||
WorkbasketService workbasketService) {
|
||||
public WorkbasketRepresentationModelAssembler(WorkbasketService workbasketService) {
|
||||
this.workbasketService = workbasketService;
|
||||
}
|
||||
|
||||
|
@ -55,12 +53,8 @@ public class WorkbasketRepresentationModelAssembler
|
|||
BeanUtils.copyProperties(wbResource, workbasket);
|
||||
|
||||
workbasket.setId(wbResource.getWorkbasketId());
|
||||
if (wbResource.getModified() != null) {
|
||||
workbasket.setModified(Instant.parse(wbResource.getModified()));
|
||||
}
|
||||
if (wbResource.getCreated() != null) {
|
||||
workbasket.setCreated(Instant.parse(wbResource.getCreated()));
|
||||
}
|
||||
workbasket.setModified(wbResource.getModified());
|
||||
workbasket.setCreated(wbResource.getCreated());
|
||||
return workbasket;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package pro.taskana.workbasket.rest.assembler;
|
||||
|
||||
import static pro.taskana.common.rest.models.TaskanaPagedModelKeys.DISTRIBUTION_TARGETS;
|
||||
import static pro.taskana.common.rest.models.TaskanaPagedModelKeys.WORKBASKETS;
|
||||
|
||||
import java.util.List;
|
||||
|
@ -13,7 +14,6 @@ import org.springframework.stereotype.Component;
|
|||
|
||||
import pro.taskana.common.rest.Mapping;
|
||||
import pro.taskana.common.rest.models.TaskanaPagedModel;
|
||||
import pro.taskana.common.rest.models.TaskanaPagedModelKeys;
|
||||
import pro.taskana.resource.rest.PageLinks;
|
||||
import pro.taskana.workbasket.api.WorkbasketService;
|
||||
import pro.taskana.workbasket.api.models.WorkbasketSummary;
|
||||
|
@ -60,10 +60,17 @@ public class WorkbasketSummaryRepresentationModelAssembler implements
|
|||
.collect(
|
||||
Collectors.collectingAndThen(
|
||||
Collectors.toList(),
|
||||
list -> new TaskanaPagedModel<>(getKey(), list, pageMetadata)));
|
||||
list -> new TaskanaPagedModel<>(WORKBASKETS, list, pageMetadata)));
|
||||
}
|
||||
|
||||
protected TaskanaPagedModelKeys getKey() {
|
||||
return WORKBASKETS;
|
||||
@PageLinks(Mapping.URL_WORKBASKET_ID_DISTRIBUTION)
|
||||
public TaskanaPagedModel<WorkbasketSummaryRepresentationModel> toDistributionTargetPageModel(
|
||||
List<WorkbasketSummary> workbasketSummaries, PageMetadata pageMetadata) {
|
||||
return workbasketSummaries.stream()
|
||||
.map(this::toModel)
|
||||
.collect(
|
||||
Collectors.collectingAndThen(
|
||||
Collectors.toList(),
|
||||
list -> new TaskanaPagedModel<>(DISTRIBUTION_TARGETS, list, pageMetadata)));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
package pro.taskana.workbasket.rest.models;
|
||||
|
||||
import java.time.Instant;
|
||||
|
||||
import pro.taskana.workbasket.api.models.Workbasket;
|
||||
|
||||
/**
|
||||
|
@ -9,49 +11,31 @@ public class WorkbasketRepresentationModel
|
|||
extends WorkbasketSummaryRepresentationModel {
|
||||
|
||||
|
||||
private String created; // ISO-8601
|
||||
private String modified; // ISO-8601
|
||||
private Instant created; // ISO-8601
|
||||
private Instant modified; // ISO-8601
|
||||
|
||||
public WorkbasketRepresentationModel() {
|
||||
}
|
||||
|
||||
public WorkbasketRepresentationModel(Workbasket workbasket) {
|
||||
super(workbasket);
|
||||
this.created = workbasket.getCreated() != null ? workbasket.getCreated().toString() : null;
|
||||
this.modified = workbasket.getModified() != null ? workbasket.getModified().toString() : null;
|
||||
this.created = workbasket.getCreated();
|
||||
this.modified = workbasket.getModified();
|
||||
}
|
||||
|
||||
public String getCreated() {
|
||||
public Instant getCreated() {
|
||||
return created;
|
||||
}
|
||||
|
||||
public void setCreated(String created) {
|
||||
public void setCreated(Instant created) {
|
||||
this.created = created;
|
||||
}
|
||||
|
||||
public String getModified() {
|
||||
public Instant getModified() {
|
||||
return modified;
|
||||
}
|
||||
|
||||
public void setModified(String modified) {
|
||||
public void setModified(Instant modified) {
|
||||
this.modified = modified;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "WorkbasketResource ["
|
||||
+ "workbasketId= "
|
||||
+ this.workbasketId
|
||||
+ "key= "
|
||||
+ this.key
|
||||
+ "name= "
|
||||
+ this.name
|
||||
+ "domain= "
|
||||
+ this.domain
|
||||
+ "type= "
|
||||
+ this.type
|
||||
+ "owner= "
|
||||
+ this.owner
|
||||
+ "]";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -103,18 +103,19 @@ class ClassificationControllerIntTest {
|
|||
ResponseEntity<TaskanaPagedModel<ClassificationSummaryRepresentationModel>> response =
|
||||
template.exchange(
|
||||
restHelper.toUrl(Mapping.URL_CLASSIFICATIONS)
|
||||
+ "?domain=DOMAIN_A&sort-by=key&order=asc&page=2&page-size=5",
|
||||
+ "?domain=DOMAIN_A&sort-by=key&order=asc&page-size=5&page=2",
|
||||
HttpMethod.GET,
|
||||
restHelper.defaultRequest(),
|
||||
CLASSIFICATION_SUMMARY_PAGE_MODEL_TYPE);
|
||||
assertThat(response.getBody().getContent()).hasSize(5);
|
||||
assertThat(response.getBody().getContent().iterator().next().getKey()).isEqualTo("L1050");
|
||||
assertThat(response.getBody().getLink(IanaLinkRelations.SELF)).isNotNull();
|
||||
String href = response
|
||||
.getBody()
|
||||
.getRequiredLink(IanaLinkRelations.SELF)
|
||||
.getHref();
|
||||
assertThat(
|
||||
response
|
||||
.getBody()
|
||||
.getRequiredLink(IanaLinkRelations.SELF)
|
||||
.getHref()
|
||||
href
|
||||
.endsWith(
|
||||
"/api/v1/classifications?"
|
||||
+ "domain=DOMAIN_A&sort-by=key&order=asc&page-size=5&page=2"))
|
||||
|
|
|
@ -9,8 +9,9 @@ import java.io.FileOutputStream;
|
|||
import java.io.IOException;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.time.Instant;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.slf4j.Logger;
|
||||
|
@ -27,28 +28,47 @@ import org.springframework.http.ResponseEntity;
|
|||
import org.springframework.util.LinkedMultiValueMap;
|
||||
import org.springframework.util.MultiValueMap;
|
||||
import org.springframework.web.client.HttpClientErrorException;
|
||||
import org.springframework.web.client.HttpStatusCodeException;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
import pro.taskana.classification.api.ClassificationService;
|
||||
import pro.taskana.classification.api.exceptions.ClassificationNotFoundException;
|
||||
import pro.taskana.classification.rest.assembler.ClassificationRepresentationModelAssembler;
|
||||
import pro.taskana.classification.rest.models.ClassificationRepresentationModel;
|
||||
import pro.taskana.classification.rest.models.ClassificationSummaryRepresentationModel;
|
||||
import pro.taskana.common.rest.Mapping;
|
||||
import pro.taskana.common.rest.RestHelper;
|
||||
import pro.taskana.common.rest.TaskanaSpringBootTest;
|
||||
import pro.taskana.common.rest.models.TaskanaPagedModel;
|
||||
import pro.taskana.common.rest.models.TaskanaPagedModelKeys;
|
||||
|
||||
/** Test classification definitions. */
|
||||
@TaskanaSpringBootTest
|
||||
class ClassificationDefinitionControllerIntTest {
|
||||
|
||||
private static final ParameterizedTypeReference<
|
||||
TaskanaPagedModel<ClassificationSummaryRepresentationModel>>
|
||||
CLASSIFICATION_SUMMARY_PAGE_MODEL_TYPE =
|
||||
new ParameterizedTypeReference<
|
||||
TaskanaPagedModel<ClassificationSummaryRepresentationModel>>() {};
|
||||
TaskanaPagedModel<ClassificationRepresentationModel>>
|
||||
CLASSIFICATION_PAGE_MODEL_TYPE =
|
||||
new ParameterizedTypeReference<TaskanaPagedModel<ClassificationRepresentationModel>>() {};
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(ClassificationController.class);
|
||||
private static RestTemplate template;
|
||||
@Autowired RestHelper restHelper;
|
||||
private ObjectMapper objMapper = new ObjectMapper();
|
||||
|
||||
private final RestHelper restHelper;
|
||||
private final ObjectMapper mapper;
|
||||
private final ClassificationService classificationService;
|
||||
private final ClassificationRepresentationModelAssembler classificationAssembler;
|
||||
|
||||
@Autowired
|
||||
ClassificationDefinitionControllerIntTest(
|
||||
RestHelper restHelper,
|
||||
ObjectMapper mapper,
|
||||
ClassificationService classificationService,
|
||||
ClassificationRepresentationModelAssembler classificationAssembler) {
|
||||
this.restHelper = restHelper;
|
||||
this.mapper = mapper;
|
||||
this.classificationService = classificationService;
|
||||
this.classificationAssembler = classificationAssembler;
|
||||
}
|
||||
|
||||
@BeforeAll
|
||||
static void init() {
|
||||
|
@ -57,27 +77,34 @@ class ClassificationDefinitionControllerIntTest {
|
|||
|
||||
@Test
|
||||
void testExportClassifications() {
|
||||
ResponseEntity<ClassificationRepresentationModel[]> response =
|
||||
ResponseEntity<TaskanaPagedModel<ClassificationRepresentationModel>> response =
|
||||
template.exchange(
|
||||
restHelper.toUrl(Mapping.URL_CLASSIFICATIONDEFINITION) + "?domain=DOMAIN_B",
|
||||
HttpMethod.GET,
|
||||
restHelper.defaultRequest(),
|
||||
ParameterizedTypeReference.forType(ClassificationRepresentationModel[].class));
|
||||
CLASSIFICATION_PAGE_MODEL_TYPE);
|
||||
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||
assertThat(response.getBody().length >= 5).isTrue();
|
||||
assertThat(response.getBody().length <= 7).isTrue();
|
||||
assertThat(response.getBody()[0]).isInstanceOf(ClassificationRepresentationModel.class);
|
||||
assertThat(response.getBody()).isNotNull();
|
||||
assertThat(response.getBody().getContent())
|
||||
.extracting(ClassificationRepresentationModel::getClassificationId)
|
||||
.containsOnlyOnce(
|
||||
"CLI:200000000000000000000000000000000015",
|
||||
"CLI:200000000000000000000000000000000017",
|
||||
"CLI:200000000000000000000000000000000018",
|
||||
"CLI:200000000000000000000000000000000003",
|
||||
"CLI:200000000000000000000000000000000004");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testExportClassificationsFromWrongDomain() {
|
||||
ResponseEntity<ClassificationRepresentationModel[]> response =
|
||||
ResponseEntity<TaskanaPagedModel<ClassificationRepresentationModel>> response =
|
||||
template.exchange(
|
||||
restHelper.toUrl(Mapping.URL_CLASSIFICATIONDEFINITION) + "?domain=ADdfe",
|
||||
HttpMethod.GET,
|
||||
restHelper.defaultRequest(),
|
||||
ParameterizedTypeReference.forType(ClassificationRepresentationModel[].class));
|
||||
assertThat(response.getBody()).isEmpty();
|
||||
CLASSIFICATION_PAGE_MODEL_TYPE);
|
||||
assertThat(response.getBody()).isNotNull();
|
||||
assertThat(response.getBody().getContent()).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -91,8 +118,8 @@ class ClassificationDefinitionControllerIntTest {
|
|||
classification.setType("TASK");
|
||||
classification.setDomain("DOMAIN_A");
|
||||
classification.setIsValidInDomain(true);
|
||||
classification.setCreated("2016-05-12T10:12:12.12Z");
|
||||
classification.setModified("2018-05-12T10:12:12.12Z");
|
||||
classification.setCreated(Instant.parse("2016-05-12T10:12:12.12Z"));
|
||||
classification.setModified(Instant.parse("2018-05-12T10:12:12.12Z"));
|
||||
classification.setName("name");
|
||||
classification.setDescription("description");
|
||||
classification.setPriority(4);
|
||||
|
@ -107,8 +134,9 @@ class ClassificationDefinitionControllerIntTest {
|
|||
classification.setCustom7("custom");
|
||||
classification.setCustom8("custom");
|
||||
|
||||
List<String> clList = new ArrayList<>();
|
||||
clList.add(objMapper.writeValueAsString(classification));
|
||||
TaskanaPagedModel<ClassificationRepresentationModel> clList =
|
||||
new TaskanaPagedModel<>(
|
||||
TaskanaPagedModelKeys.CLASSIFICATIONS, Collections.singletonList(classification));
|
||||
|
||||
ResponseEntity<Void> response = importRequest(clList);
|
||||
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.NO_CONTENT);
|
||||
|
@ -118,8 +146,9 @@ class ClassificationDefinitionControllerIntTest {
|
|||
void testFailureWhenKeyIsMissing() throws IOException {
|
||||
ClassificationRepresentationModel classification = new ClassificationRepresentationModel();
|
||||
classification.setDomain("DOMAIN_A");
|
||||
List<String> clList = new ArrayList<>();
|
||||
clList.add(objMapper.writeValueAsString(classification));
|
||||
TaskanaPagedModel<ClassificationRepresentationModel> clList =
|
||||
new TaskanaPagedModel<>(
|
||||
TaskanaPagedModelKeys.CLASSIFICATIONS, Collections.singletonList(classification));
|
||||
|
||||
try {
|
||||
importRequest(clList);
|
||||
|
@ -132,8 +161,9 @@ class ClassificationDefinitionControllerIntTest {
|
|||
void testFailureWhenDomainIsMissing() throws IOException {
|
||||
ClassificationRepresentationModel classification = new ClassificationRepresentationModel();
|
||||
classification.setKey("one");
|
||||
List<String> clList = new ArrayList<>();
|
||||
clList.add(objMapper.writeValueAsString(classification));
|
||||
TaskanaPagedModel<ClassificationRepresentationModel> clList =
|
||||
new TaskanaPagedModel<>(
|
||||
TaskanaPagedModelKeys.CLASSIFICATIONS, Collections.singletonList(classification));
|
||||
|
||||
try {
|
||||
importRequest(clList);
|
||||
|
@ -143,25 +173,25 @@ class ClassificationDefinitionControllerIntTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
void testFailureWhenUpdatingTypeOfExistingClassification() throws IOException {
|
||||
ClassificationSummaryRepresentationModel classification =
|
||||
this.getClassificationWithKeyAndDomain("T6310", "");
|
||||
void testFailureWhenUpdatingTypeOfExistingClassification() throws Exception {
|
||||
ClassificationRepresentationModel classification =
|
||||
getClassificationWithKeyAndDomain("T6310", "");
|
||||
classification.setType("DOCUMENT");
|
||||
List<String> clList = new ArrayList<>();
|
||||
clList.add(objMapper.writeValueAsString(classification));
|
||||
TaskanaPagedModel<ClassificationRepresentationModel> clList =
|
||||
new TaskanaPagedModel<>(
|
||||
TaskanaPagedModelKeys.CLASSIFICATIONS, Collections.singletonList(classification));
|
||||
|
||||
try {
|
||||
importRequest(clList);
|
||||
} catch (HttpClientErrorException e) {
|
||||
assertThat(e.getStatusCode()).isEqualTo(HttpStatus.BAD_REQUEST);
|
||||
}
|
||||
assertThatThrownBy(() -> importRequest(clList))
|
||||
.isInstanceOf(HttpClientErrorException.class)
|
||||
.extracting(e -> (HttpClientErrorException) e)
|
||||
.extracting(HttpClientErrorException::getStatusCode)
|
||||
.isEqualTo(HttpStatus.BAD_REQUEST);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testImportMultipleClassifications() throws IOException {
|
||||
ClassificationRepresentationModel classification1 =
|
||||
this.createClassification("id1", "ImportKey1", "DOMAIN_A", null, null);
|
||||
final String c1 = objMapper.writeValueAsString(classification1);
|
||||
|
||||
ClassificationRepresentationModel classification2 =
|
||||
this.createClassification(
|
||||
|
@ -169,77 +199,81 @@ class ClassificationDefinitionControllerIntTest {
|
|||
classification2.setCategory("MANUAL");
|
||||
classification2.setType("TASK");
|
||||
classification2.setIsValidInDomain(true);
|
||||
classification2.setCreated("2016-05-12T10:12:12.12Z");
|
||||
classification2.setModified("2018-05-12T10:12:12.12Z");
|
||||
classification2.setCreated(Instant.parse("2016-05-12T10:12:12.12Z"));
|
||||
classification2.setModified(Instant.parse("2018-05-12T10:12:12.12Z"));
|
||||
classification2.setName("name");
|
||||
classification2.setDescription("description");
|
||||
classification2.setPriority(4);
|
||||
classification2.setServiceLevel("P2D");
|
||||
classification2.setApplicationEntryPoint("entry1");
|
||||
String c2 = objMapper.writeValueAsString(classification2);
|
||||
|
||||
List<String> clList = new ArrayList<>();
|
||||
clList.add(c1);
|
||||
clList.add(c2);
|
||||
TaskanaPagedModel<ClassificationRepresentationModel> clList =
|
||||
new TaskanaPagedModel<>(
|
||||
TaskanaPagedModelKeys.CLASSIFICATIONS, Arrays.asList(classification1, classification2));
|
||||
|
||||
ResponseEntity<Void> response = importRequest(clList);
|
||||
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.NO_CONTENT);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testImportDuplicateClassification() throws IOException {
|
||||
void testImportDuplicateClassification() {
|
||||
ClassificationRepresentationModel classification1 = new ClassificationRepresentationModel();
|
||||
classification1.setClassificationId("id1");
|
||||
classification1.setKey("ImportKey3");
|
||||
classification1.setDomain("DOMAIN_A");
|
||||
String c1 = objMapper.writeValueAsString(classification1);
|
||||
|
||||
List<String> clList = new ArrayList<>();
|
||||
clList.add(c1);
|
||||
clList.add(c1);
|
||||
TaskanaPagedModel<ClassificationRepresentationModel> clList =
|
||||
new TaskanaPagedModel<>(
|
||||
TaskanaPagedModelKeys.CLASSIFICATIONS, Arrays.asList(classification1, classification1));
|
||||
|
||||
try {
|
||||
importRequest(clList);
|
||||
} catch (HttpClientErrorException e) {
|
||||
assertThat(e.getStatusCode()).isEqualTo(HttpStatus.CONFLICT);
|
||||
}
|
||||
assertThatThrownBy(() -> importRequest(clList))
|
||||
.isInstanceOf(HttpClientErrorException.class)
|
||||
.extracting(e -> (HttpClientErrorException) e)
|
||||
.extracting(HttpStatusCodeException::getStatusCode)
|
||||
.isEqualTo(HttpStatus.CONFLICT);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testInsertExistingClassificationWithOlderTimestamp() throws IOException {
|
||||
ClassificationSummaryRepresentationModel existingClassification =
|
||||
void testInsertExistingClassificationWithOlderTimestamp() throws Exception {
|
||||
ClassificationRepresentationModel existingClassification =
|
||||
getClassificationWithKeyAndDomain("L110107", "DOMAIN_A");
|
||||
existingClassification.setName("first new Name");
|
||||
List<String> clList = new ArrayList<>();
|
||||
clList.add(objMapper.writeValueAsString(existingClassification));
|
||||
|
||||
TaskanaPagedModel<ClassificationRepresentationModel> clList =
|
||||
new TaskanaPagedModel<>(
|
||||
TaskanaPagedModelKeys.CLASSIFICATIONS,
|
||||
Collections.singletonList(existingClassification));
|
||||
|
||||
ResponseEntity<Void> response = importRequest(clList);
|
||||
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.NO_CONTENT);
|
||||
|
||||
existingClassification.setName("second new Name");
|
||||
clList = new ArrayList<>();
|
||||
clList.add(objMapper.writeValueAsString(existingClassification));
|
||||
clList =
|
||||
new TaskanaPagedModel<>(
|
||||
TaskanaPagedModelKeys.CLASSIFICATIONS,
|
||||
Collections.singletonList(existingClassification));
|
||||
|
||||
response = importRequest(clList);
|
||||
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.NO_CONTENT);
|
||||
|
||||
ClassificationSummaryRepresentationModel testClassification =
|
||||
ClassificationRepresentationModel testClassification =
|
||||
this.getClassificationWithKeyAndDomain("L110107", "DOMAIN_A");
|
||||
assertThat(testClassification.getName()).isEqualTo("second new Name");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testHookExistingChildToNewParent() throws IOException {
|
||||
void testHookExistingChildToNewParent() throws Exception {
|
||||
final ClassificationRepresentationModel newClassification =
|
||||
createClassification("new Classification", "newClass", "DOMAIN_A", null, "L11010");
|
||||
ClassificationSummaryRepresentationModel existingClassification =
|
||||
ClassificationRepresentationModel existingClassification =
|
||||
getClassificationWithKeyAndDomain("L110102", "DOMAIN_A");
|
||||
existingClassification.setParentId("new Classification");
|
||||
existingClassification.setParentKey("newClass");
|
||||
|
||||
List<String> clList = new ArrayList<>();
|
||||
clList.add(objMapper.writeValueAsString(existingClassification));
|
||||
clList.add(objMapper.writeValueAsString(newClassification));
|
||||
TaskanaPagedModel<ClassificationRepresentationModel> clList =
|
||||
new TaskanaPagedModel<>(
|
||||
TaskanaPagedModelKeys.CLASSIFICATIONS,
|
||||
Arrays.asList(existingClassification, newClassification));
|
||||
|
||||
ResponseEntity<Void> response = importRequest(clList);
|
||||
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.NO_CONTENT);
|
||||
|
@ -259,41 +293,37 @@ class ClassificationDefinitionControllerIntTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
void testImportParentAndChildClassification() throws IOException {
|
||||
void testImportParentAndChildClassification() throws Exception {
|
||||
ClassificationRepresentationModel classification1 =
|
||||
this.createClassification("parentId", "ImportKey6", "DOMAIN_A", null, null);
|
||||
final String c1 = objMapper.writeValueAsString(classification1);
|
||||
|
||||
ClassificationRepresentationModel classification2 =
|
||||
this.createClassification("childId1", "ImportKey7", "DOMAIN_A", null, "ImportKey6");
|
||||
final String c21 = objMapper.writeValueAsString(classification2);
|
||||
classification2 =
|
||||
this.createClassification("childId2", "ImportKey8", "DOMAIN_A", "parentId", null);
|
||||
final String c22 = objMapper.writeValueAsString(classification2);
|
||||
|
||||
ClassificationRepresentationModel classification3 =
|
||||
this.createClassification("childId2", "ImportKey8", "DOMAIN_A", "parentId", null);
|
||||
ClassificationRepresentationModel classification4 =
|
||||
this.createClassification(
|
||||
"grandchildId1", "ImportKey9", "DOMAIN_A", "childId1", "ImportKey7");
|
||||
final String c31 = objMapper.writeValueAsString(classification3);
|
||||
classification3 =
|
||||
ClassificationRepresentationModel classification5 =
|
||||
this.createClassification("grandchild2", "ImportKey10", "DOMAIN_A", null, "ImportKey7");
|
||||
final String c32 = objMapper.writeValueAsString(classification3);
|
||||
|
||||
List<String> clList = new ArrayList<>();
|
||||
clList.add(c31);
|
||||
clList.add(c32);
|
||||
clList.add(c21);
|
||||
clList.add(c22);
|
||||
clList.add(c1);
|
||||
TaskanaPagedModel<ClassificationRepresentationModel> clList =
|
||||
new TaskanaPagedModel<>(
|
||||
TaskanaPagedModelKeys.CLASSIFICATIONS,
|
||||
Arrays.asList(
|
||||
classification1,
|
||||
classification2,
|
||||
classification3,
|
||||
classification4,
|
||||
classification5));
|
||||
|
||||
ResponseEntity<Void> response = importRequest(clList);
|
||||
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.NO_CONTENT);
|
||||
|
||||
ClassificationSummaryRepresentationModel parentCl =
|
||||
ClassificationRepresentationModel parentCl =
|
||||
getClassificationWithKeyAndDomain("ImportKey6", "DOMAIN_A");
|
||||
ClassificationSummaryRepresentationModel childCl =
|
||||
ClassificationRepresentationModel childCl =
|
||||
getClassificationWithKeyAndDomain("ImportKey7", "DOMAIN_A");
|
||||
ClassificationSummaryRepresentationModel grandchildCl =
|
||||
ClassificationRepresentationModel grandchildCl =
|
||||
getClassificationWithKeyAndDomain("ImportKey9", "DOMAIN_A");
|
||||
|
||||
assertThat(parentCl).isNotNull();
|
||||
|
@ -304,31 +334,27 @@ class ClassificationDefinitionControllerIntTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
void testImportParentAndChildClassificationWithKey() throws IOException {
|
||||
ClassificationRepresentationModel classification1 =
|
||||
void testImportParentAndChildClassificationWithKey() throws Exception {
|
||||
ClassificationRepresentationModel parent =
|
||||
createClassification("parent", "ImportKey11", "DOMAIN_A", null, null);
|
||||
classification1.setCustom1("parent is correct");
|
||||
String parent = objMapper.writeValueAsString(classification1);
|
||||
ClassificationRepresentationModel classification2 =
|
||||
parent.setCustom1("parent is correct");
|
||||
ClassificationRepresentationModel wrongParent =
|
||||
createClassification("wrongParent", "ImportKey11", "DOMAIN_B", null, null);
|
||||
String wrongParent = objMapper.writeValueAsString(classification2);
|
||||
ClassificationRepresentationModel classification3 =
|
||||
ClassificationRepresentationModel child =
|
||||
createClassification("child", "ImportKey13", "DOMAIN_A", null, "ImportKey11");
|
||||
String child = objMapper.writeValueAsString(classification3);
|
||||
|
||||
List<String> clList = new ArrayList<>();
|
||||
clList.add(wrongParent);
|
||||
clList.add(parent);
|
||||
clList.add(child);
|
||||
TaskanaPagedModel<ClassificationRepresentationModel> clList =
|
||||
new TaskanaPagedModel<>(
|
||||
TaskanaPagedModelKeys.CLASSIFICATIONS, Arrays.asList(parent, wrongParent, child));
|
||||
|
||||
ResponseEntity<Void> response = importRequest(clList);
|
||||
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.NO_CONTENT);
|
||||
|
||||
ClassificationSummaryRepresentationModel rightParentCl =
|
||||
ClassificationRepresentationModel rightParentCl =
|
||||
getClassificationWithKeyAndDomain("ImportKey11", "DOMAIN_A");
|
||||
ClassificationSummaryRepresentationModel wrongParentCl =
|
||||
ClassificationRepresentationModel wrongParentCl =
|
||||
getClassificationWithKeyAndDomain("ImportKey11", "DOMAIN_B");
|
||||
ClassificationSummaryRepresentationModel childCl =
|
||||
ClassificationRepresentationModel childCl =
|
||||
getClassificationWithKeyAndDomain("ImportKey13", "DOMAIN_A");
|
||||
|
||||
assertThat(rightParentCl).isNotNull();
|
||||
|
@ -339,50 +365,46 @@ class ClassificationDefinitionControllerIntTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
void testChangeParentByImportingExistingClassification()
|
||||
throws IOException, InterruptedException {
|
||||
ClassificationSummaryRepresentationModel child1 =
|
||||
void testChangeParentByImportingExistingClassification() throws Exception {
|
||||
ClassificationRepresentationModel child1 =
|
||||
this.getClassificationWithKeyAndDomain("L110105", "DOMAIN_A");
|
||||
assertThat(child1.getParentKey()).isEqualTo("L11010");
|
||||
child1.setParentId("CLI:100000000000000000000000000000000002");
|
||||
child1.setParentKey("L10303");
|
||||
final String withNewParent = objMapper.writeValueAsString(child1);
|
||||
|
||||
ClassificationSummaryRepresentationModel child2 =
|
||||
ClassificationRepresentationModel child2 =
|
||||
this.getClassificationWithKeyAndDomain("L110107", "DOMAIN_A");
|
||||
assertThat(child2.getParentKey()).isEqualTo("L11010");
|
||||
child2.setParentId("");
|
||||
child2.setParentKey("");
|
||||
String withoutParent = objMapper.writeValueAsString(child2);
|
||||
|
||||
List<String> clList = new ArrayList<>();
|
||||
clList.add(withNewParent);
|
||||
clList.add(withoutParent);
|
||||
TaskanaPagedModel<ClassificationRepresentationModel> clList =
|
||||
new TaskanaPagedModel<>(
|
||||
TaskanaPagedModelKeys.CLASSIFICATIONS, Arrays.asList(child1, child2));
|
||||
|
||||
ResponseEntity<Void> response = importRequest(clList);
|
||||
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.NO_CONTENT);
|
||||
Thread.sleep(10);
|
||||
LOGGER.debug("Wait 10 ms to give the system a chance to update");
|
||||
|
||||
ClassificationSummaryRepresentationModel childWithNewParent =
|
||||
ClassificationRepresentationModel childWithNewParent =
|
||||
this.getClassificationWithKeyAndDomain("L110105", "DOMAIN_A");
|
||||
assertThat(childWithNewParent.getParentKey()).isEqualTo(child1.getParentKey());
|
||||
|
||||
ClassificationSummaryRepresentationModel childWithoutParent =
|
||||
ClassificationRepresentationModel childWithoutParent =
|
||||
this.getClassificationWithKeyAndDomain("L110107", "DOMAIN_A");
|
||||
assertThat(childWithoutParent.getParentId()).isEqualTo(child2.getParentId());
|
||||
assertThat(childWithoutParent.getParentKey()).isEqualTo(child2.getParentKey());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailOnImportDuplicates() throws IOException {
|
||||
ClassificationSummaryRepresentationModel classification =
|
||||
void testFailOnImportDuplicates() throws Exception {
|
||||
ClassificationRepresentationModel classification =
|
||||
this.getClassificationWithKeyAndDomain("L110105", "DOMAIN_A");
|
||||
String classificationString = objMapper.writeValueAsString(classification);
|
||||
|
||||
List<String> clList = new ArrayList<>();
|
||||
clList.add(classificationString);
|
||||
clList.add(classificationString);
|
||||
TaskanaPagedModel<ClassificationRepresentationModel> clList =
|
||||
new TaskanaPagedModel<>(
|
||||
TaskanaPagedModelKeys.CLASSIFICATIONS, Arrays.asList(classification, classification));
|
||||
|
||||
assertThatThrownBy(() -> importRequest(clList))
|
||||
.isInstanceOf(HttpClientErrorException.class)
|
||||
|
@ -402,29 +424,18 @@ class ClassificationDefinitionControllerIntTest {
|
|||
return classificationRepresentationModel;
|
||||
}
|
||||
|
||||
private ClassificationSummaryRepresentationModel getClassificationWithKeyAndDomain(
|
||||
String key, String domain) {
|
||||
LOGGER.debug("Request classification with key={} in domain={}", key, domain);
|
||||
HttpEntity<String> request = new HttpEntity<>(restHelper.getHeaders());
|
||||
ResponseEntity<TaskanaPagedModel<ClassificationSummaryRepresentationModel>> response =
|
||||
template.exchange(
|
||||
restHelper.toUrl(Mapping.URL_CLASSIFICATIONS) + "?key=" + key + "&domain=" + domain,
|
||||
HttpMethod.GET,
|
||||
request,
|
||||
CLASSIFICATION_SUMMARY_PAGE_MODEL_TYPE);
|
||||
return response
|
||||
.getBody()
|
||||
.getContent()
|
||||
.toArray(new ClassificationSummaryRepresentationModel[1])[0];
|
||||
private ClassificationRepresentationModel getClassificationWithKeyAndDomain(
|
||||
String key, String domain) throws ClassificationNotFoundException {
|
||||
return classificationAssembler.toModel(classificationService.getClassification(key, domain));
|
||||
}
|
||||
|
||||
private ResponseEntity<Void> importRequest(List<String> clList) throws IOException {
|
||||
private ResponseEntity<Void> importRequest(
|
||||
TaskanaPagedModel<ClassificationRepresentationModel> clList) throws IOException {
|
||||
LOGGER.debug("Start Import");
|
||||
File tmpFile = File.createTempFile("test", ".tmp");
|
||||
OutputStreamWriter writer =
|
||||
new OutputStreamWriter(new FileOutputStream(tmpFile), StandardCharsets.UTF_8);
|
||||
writer.write(clList.toString());
|
||||
writer.close();
|
||||
mapper.writeValue(writer, clList);
|
||||
|
||||
MultiValueMap<String, Object> body = new LinkedMultiValueMap<>();
|
||||
|
||||
|
|
|
@ -3,12 +3,16 @@ package pro.taskana.common.rest;
|
|||
import com.fasterxml.jackson.databind.DeserializationFeature;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.SerializationFeature;
|
||||
import com.fasterxml.jackson.datatype.jdk8.Jdk8Module;
|
||||
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
|
||||
import com.fasterxml.jackson.module.paramnames.ParameterNamesModule;
|
||||
import java.util.Collections;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.hateoas.MediaTypes;
|
||||
import org.springframework.hateoas.mediatype.hal.Jackson2HalModule;
|
||||
import org.springframework.http.HttpEntity;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
@ -81,9 +85,11 @@ public class RestHelper {
|
|||
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
|
||||
mapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
|
||||
mapper.registerModule(new Jackson2HalModule());
|
||||
|
||||
mapper.registerModule(new ParameterNamesModule())
|
||||
.registerModule(new Jdk8Module())
|
||||
.registerModule(new JavaTimeModule());
|
||||
MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
|
||||
converter.setSupportedMediaTypes(MediaType.parseMediaTypes("application/hal+json"));
|
||||
converter.setSupportedMediaTypes(Collections.singletonList(MediaTypes.HAL_JSON));
|
||||
converter.setObjectMapper(mapper);
|
||||
|
||||
RestTemplate template = new RestTemplate();
|
||||
|
|
|
@ -27,8 +27,8 @@ class ClassificationDefinitionControllerRestDocumentation extends BaseRestDocume
|
|||
|
||||
classificationDefinitionsFieldDescriptors =
|
||||
new FieldDescriptor[] {
|
||||
subsectionWithPath("[]")
|
||||
.description("An array of <<ClassificationResource, classifications>>")
|
||||
subsectionWithPath("classifications")
|
||||
.description("An array of <<ClassificationRepresentationModels, classifications>>")
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -49,7 +49,8 @@ class ClassificationDefinitionControllerRestDocumentation extends BaseRestDocume
|
|||
|
||||
@Test
|
||||
void importClassificationDefinitions() throws Exception {
|
||||
String definitionString = "[{\"key\":\"Key0815\", \"domain\":\"DOMAIN_B\"}]";
|
||||
String definitionString =
|
||||
"{\"classifications\":[{\"key\":\"Key0815\", \"domain\":\"DOMAIN_B\"}]}";
|
||||
|
||||
this.mockMvc
|
||||
.perform(
|
||||
|
|
|
@ -406,9 +406,9 @@ class WorkbasketControllerRestDocumentation extends BaseRestDocumentation {
|
|||
this.mockMvc
|
||||
.perform(
|
||||
RestDocumentationRequestBuilders.get(
|
||||
restHelper.toUrl(
|
||||
Mapping.URL_WORKBASKET_ID_DISTRIBUTION,
|
||||
"WBI:100000000000000000000000000000000002"))
|
||||
restHelper.toUrl(
|
||||
Mapping.URL_WORKBASKET_ID_DISTRIBUTION,
|
||||
"WBI:100000000000000000000000000000000002"))
|
||||
.header("Authorization", "Basic dGVhbWxlYWRfMTp0ZWFtbGVhZF8x"))
|
||||
.andExpect(MockMvcResultMatchers.status().isOk())
|
||||
.andDo(
|
||||
|
|
|
@ -27,8 +27,10 @@ class WorkbasketDefinitionControllerRestDocumentation extends BaseRestDocumentat
|
|||
|
||||
workbasketDefinitionsFieldDescriptors =
|
||||
new FieldDescriptor[] {
|
||||
subsectionWithPath("[]")
|
||||
.description("An array of <<WorkbasketDefinitions, workbasketsDefinitions>>")
|
||||
subsectionWithPath("workbasketDefinitions")
|
||||
.description(
|
||||
"An array of <<WorkbasketDefinitionRepresentationModels, "
|
||||
+ "workbasketsDefinitions>>")
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -49,7 +51,7 @@ class WorkbasketDefinitionControllerRestDocumentation extends BaseRestDocumentat
|
|||
@Test
|
||||
void importWorkbasketDefinition() throws Exception {
|
||||
String definitionString =
|
||||
"["
|
||||
"{ \"workbasketDefinitions\": ["
|
||||
+ "{"
|
||||
+ "\"distributionTargets\":[], "
|
||||
+ "\"authorizations\":[], "
|
||||
|
@ -57,7 +59,7 @@ class WorkbasketDefinitionControllerRestDocumentation extends BaseRestDocumentat
|
|||
+ "\"domain\": \"DOMAIN_A\", \"type\":\"GROUP\" , "
|
||||
+ "\"workbasketId\":\"gibtsNed\"}"
|
||||
+ "}"
|
||||
+ "]";
|
||||
+ "]}";
|
||||
|
||||
this.mockMvc
|
||||
.perform(
|
||||
|
|
|
@ -3,8 +3,8 @@ package pro.taskana.task.rest;
|
|||
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
||||
import static pro.taskana.common.rest.RestHelper.TEMPLATE;
|
||||
|
||||
import com.fasterxml.jackson.databind.DeserializationFeature;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import java.io.BufferedReader;
|
||||
|
@ -18,7 +18,6 @@ import java.time.Instant;
|
|||
import java.time.temporal.ChronoUnit;
|
||||
import javax.sql.DataSource;
|
||||
import org.assertj.core.api.ThrowableAssert.ThrowingCallable;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
|
@ -30,7 +29,6 @@ import org.springframework.http.HttpMethod;
|
|||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.client.HttpClientErrorException;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
import pro.taskana.classification.rest.models.ClassificationSummaryRepresentationModel;
|
||||
import pro.taskana.common.rest.Mapping;
|
||||
|
@ -51,18 +49,18 @@ class TaskControllerIntTest {
|
|||
private static final ParameterizedTypeReference<TaskanaPagedModel<TaskSummaryRepresentationModel>>
|
||||
TASK_SUMMARY_PAGE_MODEL_TYPE =
|
||||
new ParameterizedTypeReference<TaskanaPagedModel<TaskSummaryRepresentationModel>>() {};
|
||||
private static RestTemplate template;
|
||||
private final RestHelper restHelper;
|
||||
private final ObjectMapper mapper;
|
||||
private final DataSource dataSource;
|
||||
|
||||
@Value("${taskana.schemaName:TASKANA}")
|
||||
public String schemaName;
|
||||
|
||||
@Autowired RestHelper restHelper;
|
||||
|
||||
@Autowired private DataSource dataSource;
|
||||
|
||||
@BeforeAll
|
||||
static void init() {
|
||||
template = RestHelper.TEMPLATE;
|
||||
@Autowired
|
||||
TaskControllerIntTest(RestHelper restHelper, ObjectMapper mapper, DataSource dataSource) {
|
||||
this.restHelper = restHelper;
|
||||
this.mapper = mapper;
|
||||
this.dataSource = dataSource;
|
||||
}
|
||||
|
||||
void resetDb() {
|
||||
|
@ -73,29 +71,27 @@ class TaskControllerIntTest {
|
|||
@Test
|
||||
void testGetAllTasks() {
|
||||
ResponseEntity<TaskanaPagedModel<TaskSummaryRepresentationModel>> response =
|
||||
template.exchange(
|
||||
TEMPLATE.exchange(
|
||||
restHelper.toUrl(Mapping.URL_TASKS),
|
||||
HttpMethod.GET,
|
||||
restHelper.defaultRequest(),
|
||||
TASK_SUMMARY_PAGE_MODEL_TYPE);
|
||||
assertThat(response.getBody()).isNotNull();
|
||||
assertThat((response.getBody()).getLink(IanaLinkRelations.SELF))
|
||||
.isNotNull();
|
||||
assertThat((response.getBody()).getLink(IanaLinkRelations.SELF)).isNotNull();
|
||||
assertThat(response.getBody().getContent()).hasSize(25);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGetAllTasksByWorkbasketId() {
|
||||
ResponseEntity<TaskanaPagedModel<TaskSummaryRepresentationModel>> response =
|
||||
template.exchange(
|
||||
TEMPLATE.exchange(
|
||||
restHelper.toUrl(Mapping.URL_TASKS)
|
||||
+ "?workbasket-id=WBI:100000000000000000000000000000000001",
|
||||
HttpMethod.GET,
|
||||
restHelper.defaultRequest(),
|
||||
TASK_SUMMARY_PAGE_MODEL_TYPE);
|
||||
assertThat(response.getBody()).isNotNull();
|
||||
assertThat((response.getBody()).getLink(IanaLinkRelations.SELF))
|
||||
.isNotNull();
|
||||
assertThat((response.getBody()).getLink(IanaLinkRelations.SELF)).isNotNull();
|
||||
assertThat(response.getBody().getContent()).hasSize(22);
|
||||
}
|
||||
|
||||
|
@ -108,7 +104,7 @@ class TaskControllerIntTest {
|
|||
Instant fourthInstant = Instant.now().minus(11, ChronoUnit.DAYS);
|
||||
|
||||
ResponseEntity<TaskanaPagedModel<TaskSummaryRepresentationModel>> response =
|
||||
template.exchange(
|
||||
TEMPLATE.exchange(
|
||||
restHelper.toUrl(Mapping.URL_TASKS)
|
||||
+ "?workbasket-id=WBI:100000000000000000000000000000000001"
|
||||
+ "&planned="
|
||||
|
@ -125,8 +121,7 @@ class TaskControllerIntTest {
|
|||
restHelper.defaultRequest(),
|
||||
TASK_SUMMARY_PAGE_MODEL_TYPE);
|
||||
assertThat(response.getBody()).isNotNull();
|
||||
assertThat((response.getBody()).getLink(IanaLinkRelations.SELF))
|
||||
.isNotNull();
|
||||
assertThat((response.getBody()).getLink(IanaLinkRelations.SELF)).isNotNull();
|
||||
assertThat(response.getBody().getContent()).hasSize(6);
|
||||
}
|
||||
|
||||
|
@ -137,7 +132,7 @@ class TaskControllerIntTest {
|
|||
Instant plannedToInstant = Instant.now().minus(3, ChronoUnit.DAYS);
|
||||
|
||||
ResponseEntity<TaskanaPagedModel<TaskSummaryRepresentationModel>> response =
|
||||
template.exchange(
|
||||
TEMPLATE.exchange(
|
||||
restHelper.toUrl(Mapping.URL_TASKS)
|
||||
+ "?workbasket-id=WBI:100000000000000000000000000000000001"
|
||||
+ "&planned-from="
|
||||
|
@ -149,8 +144,7 @@ class TaskControllerIntTest {
|
|||
restHelper.defaultRequest(),
|
||||
TASK_SUMMARY_PAGE_MODEL_TYPE);
|
||||
assertThat(response.getBody()).isNotNull();
|
||||
assertThat((response.getBody()).getLink(IanaLinkRelations.SELF))
|
||||
.isNotNull();
|
||||
assertThat((response.getBody()).getLink(IanaLinkRelations.SELF)).isNotNull();
|
||||
assertThat(response.getBody().getContent()).hasSize(3);
|
||||
}
|
||||
|
||||
|
@ -160,7 +154,7 @@ class TaskControllerIntTest {
|
|||
Instant plannedFromInstant = Instant.now().minus(6, ChronoUnit.DAYS);
|
||||
|
||||
ResponseEntity<TaskanaPagedModel<TaskSummaryRepresentationModel>> response =
|
||||
template.exchange(
|
||||
TEMPLATE.exchange(
|
||||
restHelper.toUrl(Mapping.URL_TASKS)
|
||||
+ "?workbasket-id=WBI:100000000000000000000000000000000001"
|
||||
+ "&planned-from="
|
||||
|
@ -170,25 +164,25 @@ class TaskControllerIntTest {
|
|||
restHelper.defaultRequest(),
|
||||
TASK_SUMMARY_PAGE_MODEL_TYPE);
|
||||
assertThat(response.getBody()).isNotNull();
|
||||
assertThat((response.getBody()).getLink(IanaLinkRelations.SELF))
|
||||
.isNotNull();
|
||||
assertThat((response.getBody()).getLink(IanaLinkRelations.SELF)).isNotNull();
|
||||
assertThat(response.getBody().getContent()).hasSize(4);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGetAllTasksByWorkbasketIdWithInvalidPlannedParamsCombination() {
|
||||
ThrowingCallable httpCall =
|
||||
() -> template.exchange(
|
||||
restHelper.toUrl(Mapping.URL_TASKS)
|
||||
+ "?workbasket-id=WBI:100000000000000000000000000000000001"
|
||||
+ "&planned=2020-01-22T09:44:47.453Z,,"
|
||||
+ "2020-01-19T07:44:47.453Z,2020-01-19T19:44:47.453Z,"
|
||||
+ ",2020-01-18T09:44:47.453Z"
|
||||
+ "&planned-from=2020-01-19T07:44:47.453Z"
|
||||
+ "&sort-by=planned",
|
||||
HttpMethod.GET,
|
||||
restHelper.defaultRequest(),
|
||||
TASK_SUMMARY_PAGE_MODEL_TYPE);
|
||||
() ->
|
||||
TEMPLATE.exchange(
|
||||
restHelper.toUrl(Mapping.URL_TASKS)
|
||||
+ "?workbasket-id=WBI:100000000000000000000000000000000001"
|
||||
+ "&planned=2020-01-22T09:44:47.453Z,,"
|
||||
+ "2020-01-19T07:44:47.453Z,2020-01-19T19:44:47.453Z,"
|
||||
+ ",2020-01-18T09:44:47.453Z"
|
||||
+ "&planned-from=2020-01-19T07:44:47.453Z"
|
||||
+ "&sort-by=planned",
|
||||
HttpMethod.GET,
|
||||
restHelper.defaultRequest(),
|
||||
TASK_SUMMARY_PAGE_MODEL_TYPE);
|
||||
assertThatThrownBy(httpCall)
|
||||
.isInstanceOf(HttpClientErrorException.class)
|
||||
.hasMessageContaining("400");
|
||||
|
@ -203,7 +197,7 @@ class TaskControllerIntTest {
|
|||
Instant fourthInstant = Instant.now().minus(11, ChronoUnit.DAYS);
|
||||
|
||||
ResponseEntity<TaskanaPagedModel<TaskSummaryRepresentationModel>> response =
|
||||
template.exchange(
|
||||
TEMPLATE.exchange(
|
||||
restHelper.toUrl(Mapping.URL_TASKS)
|
||||
+ "?workbasket-id=WBI:100000000000000000000000000000000001"
|
||||
+ "&due="
|
||||
|
@ -220,15 +214,14 @@ class TaskControllerIntTest {
|
|||
restHelper.defaultRequest(),
|
||||
TASK_SUMMARY_PAGE_MODEL_TYPE);
|
||||
assertThat(response.getBody()).isNotNull();
|
||||
assertThat((response.getBody()).getLink(IanaLinkRelations.SELF))
|
||||
.isNotNull();
|
||||
assertThat((response.getBody()).getLink(IanaLinkRelations.SELF)).isNotNull();
|
||||
assertThat(response.getBody().getContent()).hasSize(6);
|
||||
}
|
||||
|
||||
@Test
|
||||
void should_ReturnAllTasksByWildcardSearch_For_ProvidedSearchValue() {
|
||||
ResponseEntity<TaskanaPagedModel<TaskSummaryRepresentationModel>> response =
|
||||
template.exchange(
|
||||
TEMPLATE.exchange(
|
||||
restHelper.toUrl(Mapping.URL_TASKS)
|
||||
+ "?wildcard-search-value=%99%"
|
||||
+ "&wildcard-search-fields=NAME,custom_3,CuStOM_4",
|
||||
|
@ -236,8 +229,7 @@ class TaskControllerIntTest {
|
|||
new HttpEntity<String>(restHelper.getHeadersAdmin()),
|
||||
TASK_SUMMARY_PAGE_MODEL_TYPE);
|
||||
assertThat(response.getBody()).isNotNull();
|
||||
assertThat((response.getBody()).getLink(IanaLinkRelations.SELF))
|
||||
.isNotNull();
|
||||
assertThat((response.getBody()).getLink(IanaLinkRelations.SELF)).isNotNull();
|
||||
assertThat(response.getBody().getContent()).hasSize(4);
|
||||
}
|
||||
|
||||
|
@ -245,11 +237,12 @@ class TaskControllerIntTest {
|
|||
void should_ThrowException_When_ProvidingInvalidWildcardSearchParameters() {
|
||||
|
||||
ThrowingCallable httpCall =
|
||||
() -> template.exchange(
|
||||
restHelper.toUrl(Mapping.URL_TASKS) + "?wildcard-search-value=%rt%",
|
||||
HttpMethod.GET,
|
||||
restHelper.defaultRequest(),
|
||||
TASK_SUMMARY_PAGE_MODEL_TYPE);
|
||||
() ->
|
||||
TEMPLATE.exchange(
|
||||
restHelper.toUrl(Mapping.URL_TASKS) + "?wildcard-search-value=%rt%",
|
||||
HttpMethod.GET,
|
||||
restHelper.defaultRequest(),
|
||||
TASK_SUMMARY_PAGE_MODEL_TYPE);
|
||||
assertThatThrownBy(httpCall)
|
||||
.isInstanceOf(HttpClientErrorException.class)
|
||||
.hasMessageContaining("400")
|
||||
|
@ -257,12 +250,13 @@ class TaskControllerIntTest {
|
|||
.isEqualTo(HttpStatus.BAD_REQUEST);
|
||||
|
||||
ThrowingCallable httpCall2 =
|
||||
() -> template.exchange(
|
||||
restHelper.toUrl(Mapping.URL_TASKS)
|
||||
+ "?wildcard-search-fields=NAME,CUSTOM_3,CUSTOM_4",
|
||||
HttpMethod.GET,
|
||||
restHelper.defaultRequest(),
|
||||
TASK_SUMMARY_PAGE_MODEL_TYPE);
|
||||
() ->
|
||||
TEMPLATE.exchange(
|
||||
restHelper.toUrl(Mapping.URL_TASKS)
|
||||
+ "?wildcard-search-fields=NAME,CUSTOM_3,CUSTOM_4",
|
||||
HttpMethod.GET,
|
||||
restHelper.defaultRequest(),
|
||||
TASK_SUMMARY_PAGE_MODEL_TYPE);
|
||||
assertThatThrownBy(httpCall2)
|
||||
.isInstanceOf(HttpClientErrorException.class)
|
||||
.hasMessageContaining("400")
|
||||
|
@ -277,7 +271,7 @@ class TaskControllerIntTest {
|
|||
Instant dueToInstant = Instant.now().minus(3, ChronoUnit.DAYS);
|
||||
|
||||
ResponseEntity<TaskanaPagedModel<TaskSummaryRepresentationModel>> response =
|
||||
template.exchange(
|
||||
TEMPLATE.exchange(
|
||||
restHelper.toUrl(Mapping.URL_TASKS)
|
||||
+ "?workbasket-id=WBI:100000000000000000000000000000000001"
|
||||
+ "&due-from="
|
||||
|
@ -289,8 +283,7 @@ class TaskControllerIntTest {
|
|||
restHelper.defaultRequest(),
|
||||
TASK_SUMMARY_PAGE_MODEL_TYPE);
|
||||
assertThat(response.getBody()).isNotNull();
|
||||
assertThat((response.getBody()).getLink(IanaLinkRelations.SELF))
|
||||
.isNotNull();
|
||||
assertThat((response.getBody()).getLink(IanaLinkRelations.SELF)).isNotNull();
|
||||
assertThat(response.getBody().getContent()).hasSize(9);
|
||||
}
|
||||
|
||||
|
@ -300,7 +293,7 @@ class TaskControllerIntTest {
|
|||
Instant dueToInstant = Instant.now().minus(1, ChronoUnit.DAYS);
|
||||
|
||||
ResponseEntity<TaskanaPagedModel<TaskSummaryRepresentationModel>> response =
|
||||
template.exchange(
|
||||
TEMPLATE.exchange(
|
||||
restHelper.toUrl(Mapping.URL_TASKS)
|
||||
+ "?workbasket-id=WBI:100000000000000000000000000000000001"
|
||||
+ "&due-until="
|
||||
|
@ -310,25 +303,25 @@ class TaskControllerIntTest {
|
|||
restHelper.defaultRequest(),
|
||||
TASK_SUMMARY_PAGE_MODEL_TYPE);
|
||||
assertThat(response.getBody()).isNotNull();
|
||||
assertThat((response.getBody()).getLink(IanaLinkRelations.SELF))
|
||||
.isNotNull();
|
||||
assertThat((response.getBody()).getLink(IanaLinkRelations.SELF)).isNotNull();
|
||||
assertThat(response.getBody().getContent()).hasSize(6);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGetAllTasksByWorkbasketIdWithInvalidDueParamsCombination() {
|
||||
ThrowingCallable httpCall =
|
||||
() -> template.exchange(
|
||||
restHelper.toUrl(Mapping.URL_TASKS)
|
||||
+ "?workbasket-id=WBI:100000000000000000000000000000000001"
|
||||
+ "&due=2020-01-22T09:44:47.453Z,,"
|
||||
+ "2020-01-19T07:44:47.453Z,2020-01-19T19:44:47.453Z,"
|
||||
+ ",2020-01-18T09:44:47.453Z"
|
||||
+ "&due-from=2020-01-19T07:44:47.453Z"
|
||||
+ "&sort-by=planned",
|
||||
HttpMethod.GET,
|
||||
restHelper.defaultRequest(),
|
||||
TASK_SUMMARY_PAGE_MODEL_TYPE);
|
||||
() ->
|
||||
TEMPLATE.exchange(
|
||||
restHelper.toUrl(Mapping.URL_TASKS)
|
||||
+ "?workbasket-id=WBI:100000000000000000000000000000000001"
|
||||
+ "&due=2020-01-22T09:44:47.453Z,,"
|
||||
+ "2020-01-19T07:44:47.453Z,2020-01-19T19:44:47.453Z,"
|
||||
+ ",2020-01-18T09:44:47.453Z"
|
||||
+ "&due-from=2020-01-19T07:44:47.453Z"
|
||||
+ "&sort-by=planned",
|
||||
HttpMethod.GET,
|
||||
restHelper.defaultRequest(),
|
||||
TASK_SUMMARY_PAGE_MODEL_TYPE);
|
||||
assertThatThrownBy(httpCall)
|
||||
.isInstanceOf(HttpClientErrorException.class)
|
||||
.hasMessageContaining("400");
|
||||
|
@ -340,21 +333,20 @@ class TaskControllerIntTest {
|
|||
headers.add("Authorization", "Basic dXNlcl8xXzI6dXNlcl8xXzI="); // user_1_2
|
||||
HttpEntity<String> request = new HttpEntity<>(headers);
|
||||
ResponseEntity<TaskanaPagedModel<TaskSummaryRepresentationModel>> response =
|
||||
template.exchange(
|
||||
TEMPLATE.exchange(
|
||||
restHelper.toUrl(Mapping.URL_TASKS) + "?workbasket-key=USER_1_2&domain=DOMAIN_A",
|
||||
HttpMethod.GET,
|
||||
request,
|
||||
TASK_SUMMARY_PAGE_MODEL_TYPE);
|
||||
assertThat(response.getBody()).isNotNull();
|
||||
assertThat((response.getBody()).getLink(IanaLinkRelations.SELF))
|
||||
.isNotNull();
|
||||
assertThat((response.getBody()).getLink(IanaLinkRelations.SELF)).isNotNull();
|
||||
assertThat(response.getBody().getContent()).hasSize(20);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGetAllTasksByExternalId() {
|
||||
ResponseEntity<TaskanaPagedModel<TaskSummaryRepresentationModel>> response =
|
||||
template.exchange(
|
||||
TEMPLATE.exchange(
|
||||
restHelper.toUrl(Mapping.URL_TASKS)
|
||||
+ "?external-id=ETI:000000000000000000000000000000000003,"
|
||||
+ "ETI:000000000000000000000000000000000004",
|
||||
|
@ -362,8 +354,7 @@ class TaskControllerIntTest {
|
|||
restHelper.defaultRequest(),
|
||||
TASK_SUMMARY_PAGE_MODEL_TYPE);
|
||||
assertThat(response.getBody()).isNotNull();
|
||||
assertThat((response.getBody()).getLink(IanaLinkRelations.SELF))
|
||||
.isNotNull();
|
||||
assertThat((response.getBody()).getLink(IanaLinkRelations.SELF)).isNotNull();
|
||||
assertThat(response.getBody().getContent()).hasSize(2);
|
||||
}
|
||||
|
||||
|
@ -375,11 +366,12 @@ class TaskControllerIntTest {
|
|||
HttpEntity<String> request = new HttpEntity<>(headers);
|
||||
|
||||
ThrowingCallable httpCall =
|
||||
() -> template.exchange(
|
||||
restHelper.toUrl(Mapping.URL_TASKS) + "?workbasket-key=USER_1_2",
|
||||
HttpMethod.GET,
|
||||
request,
|
||||
TASK_SUMMARY_PAGE_MODEL_TYPE);
|
||||
() ->
|
||||
TEMPLATE.exchange(
|
||||
restHelper.toUrl(Mapping.URL_TASKS) + "?workbasket-key=USER_1_2",
|
||||
HttpMethod.GET,
|
||||
request,
|
||||
TASK_SUMMARY_PAGE_MODEL_TYPE);
|
||||
assertThatThrownBy(httpCall)
|
||||
.isInstanceOf(HttpClientErrorException.class)
|
||||
.hasMessageContaining("400");
|
||||
|
@ -388,47 +380,46 @@ class TaskControllerIntTest {
|
|||
@Test
|
||||
void testGetAllTasksWithAdminRole() {
|
||||
ResponseEntity<TaskanaPagedModel<TaskSummaryRepresentationModel>> response =
|
||||
template.exchange(
|
||||
TEMPLATE.exchange(
|
||||
restHelper.toUrl(Mapping.URL_TASKS),
|
||||
HttpMethod.GET,
|
||||
new HttpEntity<>(restHelper.getHeadersAdmin()),
|
||||
TASK_SUMMARY_PAGE_MODEL_TYPE);
|
||||
assertThat(response.getBody()).isNotNull();
|
||||
assertThat((response.getBody()).getLink(IanaLinkRelations.SELF))
|
||||
.isNotNull();
|
||||
assertThat((response.getBody()).getLink(IanaLinkRelations.SELF)).isNotNull();
|
||||
assertThat(response.getBody().getContent()).hasSize(73);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGetAllTasksKeepingFilters() {
|
||||
ResponseEntity<TaskanaPagedModel<TaskSummaryRepresentationModel>> response =
|
||||
template.exchange(
|
||||
TEMPLATE.exchange(
|
||||
restHelper.toUrl(Mapping.URL_TASKS)
|
||||
+ "?por.type=VNR&por.value=22334455&sort-by=por.value&order=desc",
|
||||
HttpMethod.GET,
|
||||
restHelper.defaultRequest(),
|
||||
TASK_SUMMARY_PAGE_MODEL_TYPE);
|
||||
assertThat(response.getBody()).isNotNull();
|
||||
assertThat((response.getBody()).getLink(IanaLinkRelations.SELF))
|
||||
.isNotNull();
|
||||
assertThat((response.getBody()).getLink(IanaLinkRelations.SELF)).isNotNull();
|
||||
assertThat(
|
||||
response
|
||||
.getBody()
|
||||
.getRequiredLink(IanaLinkRelations.SELF)
|
||||
.getHref()
|
||||
.endsWith(
|
||||
"/api/v1/tasks?por.type=VNR&por.value=22334455&sort-by=por.value&order=desc"))
|
||||
response
|
||||
.getBody()
|
||||
.getRequiredLink(IanaLinkRelations.SELF)
|
||||
.getHref()
|
||||
.endsWith(
|
||||
"/api/v1/tasks?por.type=VNR&por.value=22334455&sort-by=por.value&order=desc"))
|
||||
.isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testThrowsExceptionIfInvalidFilterIsUsed() {
|
||||
ThrowingCallable httpCall =
|
||||
() -> template.exchange(
|
||||
restHelper.toUrl(Mapping.URL_TASKS) + "?invalid=VNR",
|
||||
HttpMethod.GET,
|
||||
restHelper.defaultRequest(),
|
||||
TASK_SUMMARY_PAGE_MODEL_TYPE);
|
||||
() ->
|
||||
TEMPLATE.exchange(
|
||||
restHelper.toUrl(Mapping.URL_TASKS) + "?invalid=VNR",
|
||||
HttpMethod.GET,
|
||||
restHelper.defaultRequest(),
|
||||
TASK_SUMMARY_PAGE_MODEL_TYPE);
|
||||
assertThatThrownBy(httpCall)
|
||||
.isInstanceOf(HttpClientErrorException.class)
|
||||
.hasMessageContaining("[invalid]")
|
||||
|
@ -441,7 +432,7 @@ class TaskControllerIntTest {
|
|||
|
||||
HttpEntity<String> request = new HttpEntity<>(restHelper.getHeadersAdmin());
|
||||
ResponseEntity<TaskanaPagedModel<TaskSummaryRepresentationModel>> response =
|
||||
template.exchange(
|
||||
TEMPLATE.exchange(
|
||||
restHelper.toUrl(Mapping.URL_TASKS)
|
||||
+ "?state=READY,CLAIMED&sort-by=por.value&order=desc&page-size=5&page=14",
|
||||
HttpMethod.GET,
|
||||
|
@ -450,11 +441,11 @@ class TaskControllerIntTest {
|
|||
assertThat(response.getBody()).isNotNull();
|
||||
assertThat((response.getBody()).getContent()).hasSize(1);
|
||||
assertThat(
|
||||
response
|
||||
.getBody()
|
||||
.getRequiredLink(IanaLinkRelations.LAST)
|
||||
.getHref()
|
||||
.contains("page=14"))
|
||||
response
|
||||
.getBody()
|
||||
.getRequiredLink(IanaLinkRelations.LAST)
|
||||
.getHref()
|
||||
.contains("page=14"))
|
||||
.isTrue();
|
||||
assertThat("TKI:100000000000000000000000000000000000")
|
||||
.isEqualTo(response.getBody().getContent().iterator().next().getTaskId());
|
||||
|
@ -487,7 +478,7 @@ class TaskControllerIntTest {
|
|||
HttpEntity<String> request = new HttpEntity<>(headers);
|
||||
|
||||
ResponseEntity<TaskanaPagedModel<TaskSummaryRepresentationModel>> response =
|
||||
template.exchange(
|
||||
TEMPLATE.exchange(
|
||||
restHelper.toUrl(Mapping.URL_TASKS) + "?sort-by=due&order=desc",
|
||||
HttpMethod.GET,
|
||||
request,
|
||||
|
@ -496,7 +487,7 @@ class TaskControllerIntTest {
|
|||
assertThat((response.getBody()).getContent()).hasSize(25);
|
||||
|
||||
response =
|
||||
template.exchange(
|
||||
TEMPLATE.exchange(
|
||||
restHelper.toUrl(Mapping.URL_TASKS) + "?sort-by=due&order=desc&page-size=5&page=5",
|
||||
HttpMethod.GET,
|
||||
request,
|
||||
|
@ -504,18 +495,18 @@ class TaskControllerIntTest {
|
|||
assertThat(response.getBody()).isNotNull();
|
||||
assertThat((response.getBody()).getContent()).hasSize(5);
|
||||
assertThat(
|
||||
response.getBody().getRequiredLink(IanaLinkRelations.LAST).getHref().contains("page=5"))
|
||||
response.getBody().getRequiredLink(IanaLinkRelations.LAST).getHref().contains("page=5"))
|
||||
.isTrue();
|
||||
assertThat("TKI:000000000000000000000000000000000023")
|
||||
.isEqualTo(response.getBody().getContent().iterator().next().getTaskId());
|
||||
|
||||
assertThat(response.getBody().getLink(IanaLinkRelations.SELF)).isNotNull();
|
||||
assertThat(
|
||||
response
|
||||
.getBody()
|
||||
.getRequiredLink(IanaLinkRelations.SELF)
|
||||
.getHref()
|
||||
.endsWith("/api/v1/tasks?sort-by=due&order=desc&page-size=5&page=5"))
|
||||
response
|
||||
.getBody()
|
||||
.getRequiredLink(IanaLinkRelations.SELF)
|
||||
.getHref()
|
||||
.endsWith("/api/v1/tasks?sort-by=due&order=desc&page-size=5&page=5"))
|
||||
.isTrue();
|
||||
|
||||
assertThat(response.getBody().getLink(IanaLinkRelations.FIRST)).isNotNull();
|
||||
|
@ -533,7 +524,7 @@ class TaskControllerIntTest {
|
|||
headers.add("Authorization", "Basic dGVhbWxlYWRfMTp0ZWFtbGVhZF8x");
|
||||
HttpEntity<String> request = new HttpEntity<>(headers);
|
||||
ResponseEntity<TaskanaPagedModel<TaskSummaryRepresentationModel>> response =
|
||||
template.exchange(
|
||||
TEMPLATE.exchange(
|
||||
restHelper.toUrl(Mapping.URL_TASKS)
|
||||
+ "?por.company=00&por.system=PASystem&por.instance=00&"
|
||||
+ "por.type=VNR&por.value=22334455&sort-by=por.type&"
|
||||
|
@ -549,14 +540,14 @@ class TaskControllerIntTest {
|
|||
assertThat(response.getBody().getLink(IanaLinkRelations.SELF)).isNotNull();
|
||||
|
||||
assertThat(
|
||||
response
|
||||
.getBody()
|
||||
.getRequiredLink(IanaLinkRelations.SELF)
|
||||
.getHref()
|
||||
.endsWith(
|
||||
"/api/v1/tasks?por.company=00&por.system=PASystem&por.instance=00&"
|
||||
+ "por.type=VNR&por.value=22334455&sort-by=por.type&order=asc&"
|
||||
+ "page-size=5&page=2"))
|
||||
response
|
||||
.getBody()
|
||||
.getRequiredLink(IanaLinkRelations.SELF)
|
||||
.getHref()
|
||||
.endsWith(
|
||||
"/api/v1/tasks?por.company=00&por.system=PASystem&por.instance=00&"
|
||||
+ "por.type=VNR&por.value=22334455&sort-by=por.type&order=asc&"
|
||||
+ "page-size=5&page=2"))
|
||||
.isTrue();
|
||||
|
||||
assertThat(response.getBody().getLink(IanaLinkRelations.FIRST)).isNotNull();
|
||||
|
@ -572,7 +563,6 @@ class TaskControllerIntTest {
|
|||
con.setRequestMethod("GET");
|
||||
con.setRequestProperty("Authorization", "Basic YWRtaW46YWRtaW4=");
|
||||
assertThat(con.getResponseCode()).isEqualTo(200);
|
||||
final ObjectMapper objectMapper = new ObjectMapper();
|
||||
|
||||
BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream(), UTF_8));
|
||||
String inputLine;
|
||||
|
@ -583,7 +573,7 @@ class TaskControllerIntTest {
|
|||
in.close();
|
||||
con.disconnect();
|
||||
String response = content.toString();
|
||||
JsonNode jsonNode = objectMapper.readTree(response);
|
||||
JsonNode jsonNode = mapper.readTree(response);
|
||||
String created = jsonNode.get("created").asText();
|
||||
assertThat(response.contains("\"attachments\":[]")).isFalse();
|
||||
assertThat(created.matches("\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z")).isTrue();
|
||||
|
@ -634,8 +624,6 @@ class TaskControllerIntTest {
|
|||
in.close();
|
||||
con.disconnect();
|
||||
String updatedTask = content.toString();
|
||||
ObjectMapper mapper = new ObjectMapper();
|
||||
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
|
||||
TaskRepresentationModel originalTaskObject =
|
||||
mapper.readValue(originalTask, TaskRepresentationModel.class);
|
||||
TaskRepresentationModel updatedTaskObject =
|
||||
|
@ -649,7 +637,7 @@ class TaskControllerIntTest {
|
|||
|
||||
TaskRepresentationModel taskRepresentationModel = getTaskResourceSample();
|
||||
ResponseEntity<TaskRepresentationModel> responseCreate =
|
||||
template.exchange(
|
||||
TEMPLATE.exchange(
|
||||
restHelper.toUrl(Mapping.URL_TASKS),
|
||||
HttpMethod.POST,
|
||||
new HttpEntity<>(taskRepresentationModel, restHelper.getHeaders()),
|
||||
|
@ -663,7 +651,7 @@ class TaskControllerIntTest {
|
|||
assertThat(taskIdOfCreatedTask.startsWith("TKI:")).isTrue();
|
||||
|
||||
ResponseEntity<TaskRepresentationModel> responseDeleted =
|
||||
template.exchange(
|
||||
TEMPLATE.exchange(
|
||||
restHelper.toUrl(Mapping.URL_TASKS_ID, taskIdOfCreatedTask),
|
||||
HttpMethod.DELETE,
|
||||
new HttpEntity<>(restHelper.getHeadersAdmin()),
|
||||
|
@ -680,15 +668,16 @@ class TaskControllerIntTest {
|
|||
void testCreateWithPlannedAndDueDate() {
|
||||
TaskRepresentationModel taskRepresentationModel = getTaskResourceSample();
|
||||
Instant now = Instant.now();
|
||||
taskRepresentationModel.setPlanned(now.toString());
|
||||
taskRepresentationModel.setDue(now.toString());
|
||||
taskRepresentationModel.setPlanned(now);
|
||||
taskRepresentationModel.setDue(now);
|
||||
|
||||
ThrowingCallable httpCall =
|
||||
() -> template.exchange(
|
||||
restHelper.toUrl(Mapping.URL_TASKS),
|
||||
HttpMethod.POST,
|
||||
new HttpEntity<>(taskRepresentationModel, restHelper.getHeaders()),
|
||||
ParameterizedTypeReference.forType(TaskRepresentationModel.class));
|
||||
() ->
|
||||
TEMPLATE.exchange(
|
||||
restHelper.toUrl(Mapping.URL_TASKS),
|
||||
HttpMethod.POST,
|
||||
new HttpEntity<>(taskRepresentationModel, restHelper.getHeaders()),
|
||||
ParameterizedTypeReference.forType(TaskRepresentationModel.class));
|
||||
assertThatThrownBy(httpCall).isInstanceOf(HttpClientErrorException.class);
|
||||
}
|
||||
|
||||
|
@ -744,7 +733,7 @@ class TaskControllerIntTest {
|
|||
|
||||
// retrieve task from Rest Api
|
||||
ResponseEntity<TaskRepresentationModel> getTaskResponse =
|
||||
template.exchange(
|
||||
TEMPLATE.exchange(
|
||||
restHelper.toUrl(Mapping.URL_TASKS_ID, claimed_task_id),
|
||||
HttpMethod.GET,
|
||||
new HttpEntity<>(restHelper.getHeadersUser_1_2()),
|
||||
|
@ -758,7 +747,7 @@ class TaskControllerIntTest {
|
|||
|
||||
// cancel claim
|
||||
ResponseEntity<TaskRepresentationModel> cancelClaimResponse =
|
||||
template.exchange(
|
||||
TEMPLATE.exchange(
|
||||
restHelper.toUrl(Mapping.URL_TASKS_ID_CLAIM, claimed_task_id),
|
||||
HttpMethod.DELETE,
|
||||
new HttpEntity<>(restHelper.getHeadersUser_1_2()),
|
||||
|
@ -781,7 +770,7 @@ class TaskControllerIntTest {
|
|||
|
||||
// retrieve task from Rest Api
|
||||
ResponseEntity<TaskRepresentationModel> responseGet =
|
||||
template.exchange(
|
||||
TEMPLATE.exchange(
|
||||
restHelper.toUrl(Mapping.URL_TASKS_ID, claimed_task_id),
|
||||
HttpMethod.GET,
|
||||
new HttpEntity<>(restHelper.getHeadersUser_1_2()),
|
||||
|
@ -794,11 +783,12 @@ class TaskControllerIntTest {
|
|||
|
||||
// try to cancel claim
|
||||
ThrowingCallable httpCall =
|
||||
() -> template.exchange(
|
||||
restHelper.toUrl(Mapping.URL_TASKS_ID_CLAIM, claimed_task_id),
|
||||
HttpMethod.DELETE,
|
||||
new HttpEntity<>(restHelper.getHeadersUser_1_2()),
|
||||
ParameterizedTypeReference.forType(TaskRepresentationModel.class));
|
||||
() ->
|
||||
TEMPLATE.exchange(
|
||||
restHelper.toUrl(Mapping.URL_TASKS_ID_CLAIM, claimed_task_id),
|
||||
HttpMethod.DELETE,
|
||||
new HttpEntity<>(restHelper.getHeadersUser_1_2()),
|
||||
ParameterizedTypeReference.forType(TaskRepresentationModel.class));
|
||||
assertThatThrownBy(httpCall)
|
||||
.extracting(ex -> ((HttpClientErrorException) ex).getStatusCode())
|
||||
.isEqualTo(HttpStatus.CONFLICT);
|
||||
|
@ -812,7 +802,7 @@ class TaskControllerIntTest {
|
|||
|
||||
// retrieve task from Rest Api
|
||||
ResponseEntity<TaskRepresentationModel> responseGet =
|
||||
template.exchange(
|
||||
TEMPLATE.exchange(
|
||||
taskUrlString,
|
||||
HttpMethod.GET,
|
||||
new HttpEntity<>(restHelper.getHeadersUser_1_2()),
|
||||
|
@ -828,7 +818,7 @@ class TaskControllerIntTest {
|
|||
final String anyUserName = "dummyUser";
|
||||
theTaskRepresentationModel.setOwner(anyUserName);
|
||||
ResponseEntity<TaskRepresentationModel> responseUpdate =
|
||||
template.exchange(
|
||||
TEMPLATE.exchange(
|
||||
taskUrlString,
|
||||
HttpMethod.PUT,
|
||||
new HttpEntity<>(theTaskRepresentationModel, restHelper.getHeadersUser_1_2()),
|
||||
|
@ -848,7 +838,7 @@ class TaskControllerIntTest {
|
|||
|
||||
// retrieve task from Rest Api
|
||||
ResponseEntity<TaskRepresentationModel> responseGet =
|
||||
template.exchange(
|
||||
TEMPLATE.exchange(
|
||||
taskUrlString,
|
||||
HttpMethod.GET,
|
||||
new HttpEntity<>(restHelper.getHeadersUser_1_2()),
|
||||
|
@ -865,11 +855,12 @@ class TaskControllerIntTest {
|
|||
theTaskRepresentationModel.setOwner(anyUserName);
|
||||
|
||||
ThrowingCallable httpCall =
|
||||
() -> template.exchange(
|
||||
taskUrlString,
|
||||
HttpMethod.PUT,
|
||||
new HttpEntity<>(theTaskRepresentationModel, restHelper.getHeadersUser_1_2()),
|
||||
ParameterizedTypeReference.forType(TaskRepresentationModel.class));
|
||||
() ->
|
||||
TEMPLATE.exchange(
|
||||
taskUrlString,
|
||||
HttpMethod.PUT,
|
||||
new HttpEntity<>(theTaskRepresentationModel, restHelper.getHeadersUser_1_2()),
|
||||
ParameterizedTypeReference.forType(TaskRepresentationModel.class));
|
||||
assertThatThrownBy(httpCall)
|
||||
.isInstanceOf(HttpClientErrorException.class)
|
||||
.hasMessageContaining("409");
|
||||
|
@ -881,8 +872,7 @@ class TaskControllerIntTest {
|
|||
classificationResource.setKey("L11010");
|
||||
WorkbasketSummaryRepresentationModel workbasketSummary =
|
||||
new WorkbasketSummaryRepresentationModel();
|
||||
workbasketSummary.setWorkbasketId(
|
||||
"WBI:100000000000000000000000000000000004");
|
||||
workbasketSummary.setWorkbasketId("WBI:100000000000000000000000000000000004");
|
||||
|
||||
ObjectReference objectReference = new ObjectReference();
|
||||
objectReference.setCompany("MyCompany1");
|
||||
|
@ -893,8 +883,7 @@ class TaskControllerIntTest {
|
|||
|
||||
TaskRepresentationModel taskRepresentationModel = new TaskRepresentationModel();
|
||||
taskRepresentationModel.setClassificationSummary(classificationResource);
|
||||
taskRepresentationModel.setWorkbasketSummary(
|
||||
workbasketSummary);
|
||||
taskRepresentationModel.setWorkbasketSummary(workbasketSummary);
|
||||
taskRepresentationModel.setPrimaryObjRef(objectReference);
|
||||
return taskRepresentationModel;
|
||||
}
|
||||
|
|
|
@ -68,12 +68,12 @@ class TaskRepresentationModelAssemberTest {
|
|||
TaskRepresentationModel resource = new TaskRepresentationModel();
|
||||
resource.setTaskId("taskId");
|
||||
resource.setExternalId("externalId");
|
||||
resource.setCreated("2019-09-13T08:44:17.588Z");
|
||||
resource.setClaimed("2019-09-13T08:44:17.588Z");
|
||||
resource.setCompleted("2019-09-13T08:44:17.588Z");
|
||||
resource.setModified("2019-09-13T08:44:17.588Z");
|
||||
resource.setPlanned("2019-09-13T08:44:17.588Z");
|
||||
resource.setDue("2019-09-13T08:44:17.588Z");
|
||||
resource.setCreated(Instant.parse("2019-09-13T08:44:17.588Z"));
|
||||
resource.setClaimed(Instant.parse("2019-09-13T08:44:17.588Z"));
|
||||
resource.setCompleted(Instant.parse("2019-09-13T08:44:17.588Z"));
|
||||
resource.setModified(Instant.parse("2019-09-13T08:44:17.588Z"));
|
||||
resource.setPlanned(Instant.parse("2019-09-13T08:44:17.588Z"));
|
||||
resource.setDue(Instant.parse("2019-09-13T08:44:17.588Z"));
|
||||
resource.setName("name");
|
||||
resource.setCreator("creator");
|
||||
resource.setDescription("desc");
|
||||
|
|
|
@ -100,21 +100,11 @@ class TaskSummaryAssemblerTest {
|
|||
void testEquality(TaskSummaryImpl taskSummary, TaskSummaryRepresentationModel resource) {
|
||||
Assert.assertEquals(taskSummary.getId(), resource.getTaskId());
|
||||
Assert.assertEquals(taskSummary.getExternalId(), resource.getExternalId());
|
||||
Assert.assertEquals(
|
||||
taskSummary.getCreated() == null ? null : taskSummary.getCreated().toString(),
|
||||
resource.getCreated());
|
||||
Assert.assertEquals(
|
||||
taskSummary.getClaimed() == null ? null : taskSummary.getClaimed().toString(),
|
||||
resource.getClaimed());
|
||||
Assert.assertEquals(
|
||||
taskSummary.getCompleted() == null ? null : taskSummary.getCompleted().toString(),
|
||||
resource.getCompleted());
|
||||
Assert.assertEquals(
|
||||
taskSummary.getModified() == null ? null : taskSummary.getModified().toString(),
|
||||
resource.getModified());
|
||||
Assert.assertEquals(
|
||||
taskSummary.getPlanned() == null ? null : taskSummary.getPlanned().toString(),
|
||||
resource.getPlanned());
|
||||
Assert.assertEquals(taskSummary.getCreated(), resource.getCreated());
|
||||
Assert.assertEquals(taskSummary.getClaimed(), resource.getClaimed());
|
||||
Assert.assertEquals(taskSummary.getCompleted(), resource.getCompleted());
|
||||
Assert.assertEquals(taskSummary.getModified(), resource.getModified());
|
||||
Assert.assertEquals(taskSummary.getPlanned(), resource.getPlanned());
|
||||
Assert.assertEquals(taskSummary.getDescription(), resource.getDescription());
|
||||
Assert.assertEquals(taskSummary.getName(), resource.getName());
|
||||
Assert.assertEquals(taskSummary.getCreator(), resource.getCreator());
|
||||
|
|
|
@ -2,11 +2,11 @@ package pro.taskana.workbasket.rest;
|
|||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
||||
import static pro.taskana.common.rest.RestHelper.TEMPLATE;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import java.time.Instant;
|
||||
import org.assertj.core.api.ThrowableAssert.ThrowingCallable;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.core.ParameterizedTypeReference;
|
||||
|
@ -17,7 +17,6 @@ import org.springframework.http.HttpMethod;
|
|||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.client.HttpClientErrorException;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
import pro.taskana.common.rest.Mapping;
|
||||
import pro.taskana.common.rest.RestHelper;
|
||||
|
@ -42,46 +41,49 @@ class WorkbasketControllerIntTest {
|
|||
WORKBASKET_SUMMARY_PAGE_MODEL_TYPE =
|
||||
new ParameterizedTypeReference<
|
||||
TaskanaPagedModel<WorkbasketSummaryRepresentationModel>>() {};
|
||||
private static RestTemplate template;
|
||||
@Autowired RestHelper restHelper;
|
||||
private final RestHelper restHelper;
|
||||
private final ObjectMapper mapper;
|
||||
|
||||
@BeforeAll
|
||||
static void init() {
|
||||
template = RestHelper.TEMPLATE;
|
||||
@Autowired
|
||||
WorkbasketControllerIntTest(RestHelper restHelper, ObjectMapper mapper) {
|
||||
this.restHelper = restHelper;
|
||||
this.mapper = mapper;
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGetWorkbasket() {
|
||||
ResponseEntity<WorkbasketRepresentationModel> response =
|
||||
template.exchange(
|
||||
TEMPLATE.exchange(
|
||||
restHelper.toUrl(Mapping.URL_WORKBASKET_ID, "WBI:100000000000000000000000000000000006"),
|
||||
HttpMethod.GET,
|
||||
restHelper.defaultRequest(),
|
||||
ParameterizedTypeReference.forType(WorkbasketRepresentationModel.class));
|
||||
assertThat(response.getBody()).isNotNull();
|
||||
assertThat(response.getBody().getLink(IanaLinkRelations.SELF)).isNotNull();
|
||||
assertThat(response.getHeaders().getContentType().toString())
|
||||
.isEqualTo(MediaTypes.HAL_JSON_VALUE);
|
||||
assertThat(response.getHeaders().getContentType()).isEqualTo(MediaTypes.HAL_JSON);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGetAllWorkbaskets() {
|
||||
ResponseEntity<TaskanaPagedModel<WorkbasketSummaryRepresentationModel>> response =
|
||||
template.exchange(
|
||||
TEMPLATE.exchange(
|
||||
restHelper.toUrl(Mapping.URL_WORKBASKET),
|
||||
HttpMethod.GET,
|
||||
restHelper.defaultRequest(),
|
||||
WORKBASKET_SUMMARY_PAGE_MODEL_TYPE);
|
||||
assertThat(response.getBody()).isNotNull();
|
||||
assertThat(response.getBody().getLink(IanaLinkRelations.SELF)).isNotNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGetAllWorkbasketsBusinessAdminHasOpenPermission() {
|
||||
ResponseEntity<TaskanaPagedModel<WorkbasketSummaryRepresentationModel>> response =
|
||||
template.exchange(
|
||||
TEMPLATE.exchange(
|
||||
restHelper.toUrl(Mapping.URL_WORKBASKET) + "?required-permission=OPEN",
|
||||
HttpMethod.GET,
|
||||
restHelper.defaultRequest(),
|
||||
WORKBASKET_SUMMARY_PAGE_MODEL_TYPE);
|
||||
assertThat(response.getBody()).isNotNull();
|
||||
assertThat(response.getBody().getRequiredLink(IanaLinkRelations.SELF)).isNotNull();
|
||||
assertThat(response.getBody().getContent()).hasSize(3);
|
||||
}
|
||||
|
@ -90,11 +92,12 @@ class WorkbasketControllerIntTest {
|
|||
void testGetAllWorkbasketsKeepingFilters() {
|
||||
String parameters = "?type=PERSONAL&sort-by=key&order=desc";
|
||||
ResponseEntity<TaskanaPagedModel<WorkbasketSummaryRepresentationModel>> response =
|
||||
template.exchange(
|
||||
TEMPLATE.exchange(
|
||||
restHelper.toUrl(Mapping.URL_WORKBASKET) + parameters,
|
||||
HttpMethod.GET,
|
||||
restHelper.defaultRequest(),
|
||||
WORKBASKET_SUMMARY_PAGE_MODEL_TYPE);
|
||||
assertThat(response.getBody()).isNotNull();
|
||||
assertThat(response.getBody().getLink(IanaLinkRelations.SELF)).isNotNull();
|
||||
assertThat(
|
||||
response
|
||||
|
@ -108,11 +111,12 @@ class WorkbasketControllerIntTest {
|
|||
@Test
|
||||
void testThrowsExceptionIfInvalidFilterIsUsed() {
|
||||
ThrowingCallable httpCall =
|
||||
() -> template.exchange(
|
||||
restHelper.toUrl(Mapping.URL_WORKBASKET) + "?invalid=PERSONAL",
|
||||
HttpMethod.GET,
|
||||
restHelper.defaultRequest(),
|
||||
WORKBASKET_SUMMARY_PAGE_MODEL_TYPE);
|
||||
() ->
|
||||
TEMPLATE.exchange(
|
||||
restHelper.toUrl(Mapping.URL_WORKBASKET) + "?invalid=PERSONAL",
|
||||
HttpMethod.GET,
|
||||
restHelper.defaultRequest(),
|
||||
WORKBASKET_SUMMARY_PAGE_MODEL_TYPE);
|
||||
assertThatThrownBy(httpCall)
|
||||
.isInstanceOf(HttpClientErrorException.class)
|
||||
.hasMessageContaining("[invalid]")
|
||||
|
@ -125,10 +129,8 @@ class WorkbasketControllerIntTest {
|
|||
|
||||
String workbasketId = "WBI:100000000000000000000000000000000001";
|
||||
|
||||
final ObjectMapper mapper = new ObjectMapper();
|
||||
|
||||
ResponseEntity<WorkbasketRepresentationModel> initialWorkbasketResourceRequestResponse =
|
||||
template.exchange(
|
||||
TEMPLATE.exchange(
|
||||
restHelper.toUrl(Mapping.URL_WORKBASKET_ID, workbasketId),
|
||||
HttpMethod.GET,
|
||||
new HttpEntity<String>(restHelper.getHeaders()),
|
||||
|
@ -137,16 +139,17 @@ class WorkbasketControllerIntTest {
|
|||
WorkbasketRepresentationModel workbasketRepresentationModel =
|
||||
initialWorkbasketResourceRequestResponse.getBody();
|
||||
|
||||
assertThat(workbasketRepresentationModel).isNotNull();
|
||||
workbasketRepresentationModel.setKey("GPK_KSC");
|
||||
workbasketRepresentationModel.setDomain("DOMAIN_A");
|
||||
workbasketRepresentationModel.setType(WorkbasketType.PERSONAL);
|
||||
workbasketRepresentationModel.setName("was auch immer");
|
||||
workbasketRepresentationModel.setOwner("Joerg");
|
||||
workbasketRepresentationModel.setModified(String.valueOf(Instant.now()));
|
||||
workbasketRepresentationModel.setModified(Instant.now());
|
||||
|
||||
ThrowingCallable httpCall =
|
||||
() -> {
|
||||
template.exchange(
|
||||
TEMPLATE.exchange(
|
||||
restHelper.toUrl(Mapping.URL_WORKBASKET_ID, workbasketId),
|
||||
HttpMethod.PUT,
|
||||
new HttpEntity<>(
|
||||
|
@ -166,7 +169,7 @@ class WorkbasketControllerIntTest {
|
|||
|
||||
ThrowingCallable httpCall =
|
||||
() -> {
|
||||
template.exchange(
|
||||
TEMPLATE.exchange(
|
||||
restHelper.toUrl(Mapping.URL_WORKBASKET_ID, workbasketId),
|
||||
HttpMethod.GET,
|
||||
new HttpEntity<String>(restHelper.getHeaders()),
|
||||
|
@ -183,11 +186,12 @@ class WorkbasketControllerIntTest {
|
|||
|
||||
String parameters = "?sort-by=key&order=desc&page-size=5&page=2";
|
||||
ResponseEntity<TaskanaPagedModel<WorkbasketSummaryRepresentationModel>> response =
|
||||
template.exchange(
|
||||
TEMPLATE.exchange(
|
||||
restHelper.toUrl(Mapping.URL_WORKBASKET) + parameters,
|
||||
HttpMethod.GET,
|
||||
restHelper.defaultRequest(),
|
||||
WORKBASKET_SUMMARY_PAGE_MODEL_TYPE);
|
||||
assertThat(response.getBody()).isNotNull();
|
||||
assertThat(response.getBody().getContent()).hasSize(5);
|
||||
assertThat(response.getBody().getContent().iterator().next().getKey()).isEqualTo("USER_1_1");
|
||||
assertThat(response.getBody().getLink(IanaLinkRelations.SELF)).isNotNull();
|
||||
|
@ -210,7 +214,7 @@ class WorkbasketControllerIntTest {
|
|||
String workbasketID = "WBI:100000000000000000000000000000000005";
|
||||
|
||||
ResponseEntity<?> response =
|
||||
template.exchange(
|
||||
TEMPLATE.exchange(
|
||||
restHelper.toUrl(Mapping.URL_WORKBASKET_ID, workbasketID),
|
||||
HttpMethod.DELETE,
|
||||
new HttpEntity<>(restHelper.getHeadersBusinessAdmin()),
|
||||
|
@ -224,7 +228,7 @@ class WorkbasketControllerIntTest {
|
|||
|
||||
ThrowingCallable call =
|
||||
() ->
|
||||
template.exchange(
|
||||
TEMPLATE.exchange(
|
||||
restHelper.toUrl(Mapping.URL_WORKBASKET_ID, workbasketWithNonCompletedTasks),
|
||||
HttpMethod.DELETE,
|
||||
new HttpEntity<>(restHelper.getHeadersBusinessAdmin()),
|
||||
|
@ -238,7 +242,7 @@ class WorkbasketControllerIntTest {
|
|||
@Test
|
||||
void testRemoveWorkbasketAsDistributionTarget() {
|
||||
ResponseEntity<?> response =
|
||||
template.exchange(
|
||||
TEMPLATE.exchange(
|
||||
restHelper.toUrl(
|
||||
Mapping.URL_WORKBASKET_ID_DISTRIBUTION, "WBI:100000000000000000000000000000000007"),
|
||||
HttpMethod.DELETE,
|
||||
|
@ -247,47 +251,47 @@ class WorkbasketControllerIntTest {
|
|||
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.NO_CONTENT);
|
||||
|
||||
ResponseEntity<TaskanaPagedModel<WorkbasketSummaryRepresentationModel>> response2 =
|
||||
template.exchange(
|
||||
TEMPLATE.exchange(
|
||||
restHelper.toUrl(
|
||||
Mapping.URL_WORKBASKET_ID_DISTRIBUTION, "WBI:100000000000000000000000000000000002"),
|
||||
HttpMethod.GET,
|
||||
restHelper.defaultRequest(),
|
||||
WORKBASKET_SUMMARY_PAGE_MODEL_TYPE);
|
||||
assertThat(response2.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||
assertThat(
|
||||
response2.getBody().getContent().stream()
|
||||
.map(WorkbasketSummaryRepresentationModel::getWorkbasketId)
|
||||
.noneMatch("WBI:100000000000000000000000000000000007"::equals))
|
||||
.isTrue();
|
||||
assertThat(response2.getBody()).isNotNull();
|
||||
assertThat(response2.getBody().getContent())
|
||||
.extracting(WorkbasketSummaryRepresentationModel::getWorkbasketId)
|
||||
.doesNotContain("WBI:100000000000000000000000000000000007");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGetWorkbasketAccessItems() {
|
||||
ResponseEntity<TaskanaPagedModel<WorkbasketAccessItemRepresentationModel>> response =
|
||||
template.exchange(
|
||||
TEMPLATE.exchange(
|
||||
restHelper.toUrl(
|
||||
Mapping.URL_WORKBASKET_ID_ACCESSITEMS, "WBI:100000000000000000000000000000000005"),
|
||||
HttpMethod.GET,
|
||||
restHelper.defaultRequest(),
|
||||
WORKBASKET_ACCESS_ITEM_PAGE_MODEL_TYPE);
|
||||
assertThat(response.getBody()).isNotNull();
|
||||
assertThat(response.getBody().getLink(IanaLinkRelations.SELF)).isNotNull();
|
||||
assertThat(response.getHeaders().getContentType().toString())
|
||||
.isEqualTo(MediaTypes.HAL_JSON_VALUE);
|
||||
assertThat(response.getHeaders().getContentType()).isEqualTo(MediaTypes.HAL_JSON);
|
||||
assertThat(response.getBody().getContent()).hasSize(3);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGetWorkbasketDistributionTargets() {
|
||||
ResponseEntity<TaskanaPagedModel<WorkbasketSummaryRepresentationModel>> response =
|
||||
template.exchange(
|
||||
TEMPLATE.exchange(
|
||||
restHelper.toUrl(
|
||||
Mapping.URL_WORKBASKET_ID_DISTRIBUTION, "WBI:100000000000000000000000000000000001"),
|
||||
HttpMethod.GET,
|
||||
restHelper.defaultRequest(),
|
||||
WORKBASKET_SUMMARY_PAGE_MODEL_TYPE);
|
||||
assertThat(response.getBody()).isNotNull();
|
||||
assertThat(response.getBody().getLink(IanaLinkRelations.SELF)).isNotNull();
|
||||
assertThat(response.getHeaders().getContentType().toString())
|
||||
.isEqualTo(MediaTypes.HAL_JSON_VALUE);
|
||||
assertThat(response.getHeaders().getContentType())
|
||||
.isEqualTo(MediaTypes.HAL_JSON);
|
||||
assertThat(response.getBody().getContent()).hasSize(4);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,22 +3,21 @@ package pro.taskana.workbasket.rest;
|
|||
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||
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 static pro.taskana.common.rest.RestHelper.TEMPLATE;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
import javax.sql.DataSource;
|
||||
import org.assertj.core.api.ThrowableAssert.ThrowingCallable;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
@ -34,11 +33,13 @@ import org.springframework.http.ResponseEntity;
|
|||
import org.springframework.util.LinkedMultiValueMap;
|
||||
import org.springframework.util.MultiValueMap;
|
||||
import org.springframework.web.client.HttpClientErrorException;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
import org.springframework.web.client.HttpStatusCodeException;
|
||||
|
||||
import pro.taskana.common.rest.Mapping;
|
||||
import pro.taskana.common.rest.RestHelper;
|
||||
import pro.taskana.common.rest.TaskanaSpringBootTest;
|
||||
import pro.taskana.common.rest.models.TaskanaPagedModel;
|
||||
import pro.taskana.common.rest.models.TaskanaPagedModelKeys;
|
||||
import pro.taskana.sampledata.SampleDataGenerator;
|
||||
import pro.taskana.workbasket.rest.models.WorkbasketDefinitionRepresentationModel;
|
||||
|
||||
|
@ -46,20 +47,19 @@ import pro.taskana.workbasket.rest.models.WorkbasketDefinitionRepresentationMode
|
|||
@TaskanaSpringBootTest
|
||||
class WorkbasketDefinitionControllerIntTest {
|
||||
|
||||
private static RestTemplate template;
|
||||
private final ObjectMapper objMapper;
|
||||
private final RestHelper restHelper;
|
||||
private final DataSource dataSource;
|
||||
|
||||
@Value("${taskana.schemaName:TASKANA}")
|
||||
String schemaName;
|
||||
|
||||
ObjectMapper objMapper = new ObjectMapper();
|
||||
|
||||
@Autowired RestHelper restHelper;
|
||||
|
||||
@Autowired private DataSource dataSource;
|
||||
|
||||
@BeforeAll
|
||||
static void init() {
|
||||
template = RestHelper.TEMPLATE;
|
||||
@Autowired
|
||||
WorkbasketDefinitionControllerIntTest(
|
||||
ObjectMapper objMapper, RestHelper restHelper, DataSource dataSource) {
|
||||
this.objMapper = objMapper;
|
||||
this.restHelper = restHelper;
|
||||
this.dataSource = dataSource;
|
||||
}
|
||||
|
||||
@BeforeEach
|
||||
|
@ -70,17 +70,18 @@ class WorkbasketDefinitionControllerIntTest {
|
|||
|
||||
@Test
|
||||
void testExportWorkbasketFromDomain() {
|
||||
ResponseEntity<List<WorkbasketDefinitionRepresentationModel>> response =
|
||||
ResponseEntity<TaskanaPagedModel<WorkbasketDefinitionRepresentationModel>> response =
|
||||
executeExportRequestForDomain("DOMAIN_A");
|
||||
|
||||
assertThat(response.getBody()).isNotNull();
|
||||
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||
assertThat(response.getBody().get(0))
|
||||
.isInstanceOf(WorkbasketDefinitionRepresentationModel.class);
|
||||
assertThat(response.getBody().getContent())
|
||||
.hasOnlyElementsOfType(WorkbasketDefinitionRepresentationModel.class);
|
||||
|
||||
boolean allAuthorizationsAreEmpty = true;
|
||||
boolean allDistributionTargetsAreEmpty = true;
|
||||
for (WorkbasketDefinitionRepresentationModel workbasketDefinition : response.getBody()) {
|
||||
for (WorkbasketDefinitionRepresentationModel workbasketDefinition :
|
||||
response.getBody().getContent()) {
|
||||
if (allAuthorizationsAreEmpty && !workbasketDefinition.getAuthorizations().isEmpty()) {
|
||||
allAuthorizationsAreEmpty = false;
|
||||
}
|
||||
|
@ -98,24 +99,29 @@ class WorkbasketDefinitionControllerIntTest {
|
|||
|
||||
@Test
|
||||
void testExportWorkbasketsFromWrongDomain() {
|
||||
ResponseEntity<List<WorkbasketDefinitionRepresentationModel>> response =
|
||||
ResponseEntity<TaskanaPagedModel<WorkbasketDefinitionRepresentationModel>> response =
|
||||
executeExportRequestForDomain("wrongDomain");
|
||||
assertThat(response.getBody()).isEmpty();
|
||||
assertThat(response.getBody()).isNotNull();
|
||||
assertThat(response.getBody().getContent()).isEmpty();
|
||||
assertThat(response.getBody().getKey()).isSameAs(TaskanaPagedModelKeys.WORKBASKET_DEFINITIONS);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testImportEveryWorkbasketFromDomainA() throws IOException {
|
||||
List<WorkbasketDefinitionRepresentationModel> wbList =
|
||||
TaskanaPagedModel<WorkbasketDefinitionRepresentationModel> wbList =
|
||||
executeExportRequestForDomain("DOMAIN_A").getBody();
|
||||
for (WorkbasketDefinitionRepresentationModel w : wbList) {
|
||||
assertThat(wbList).isNotNull();
|
||||
for (WorkbasketDefinitionRepresentationModel w : wbList.getContent()) {
|
||||
expectStatusWhenExecutingImportRequestOfWorkbaskets(HttpStatus.NO_CONTENT, w);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void testImportWorkbasketWithoutDistributionTargets() throws IOException {
|
||||
WorkbasketDefinitionRepresentationModel w =
|
||||
executeExportRequestForDomain("DOMAIN_A").getBody().get(0);
|
||||
TaskanaPagedModel<WorkbasketDefinitionRepresentationModel> pagedModel =
|
||||
executeExportRequestForDomain("DOMAIN_A").getBody();
|
||||
assertThat(pagedModel).isNotNull();
|
||||
WorkbasketDefinitionRepresentationModel w = pagedModel.getContent().iterator().next();
|
||||
w.setDistributionTargets(new HashSet<>());
|
||||
|
||||
this.expectStatusWhenExecutingImportRequestOfWorkbaskets(HttpStatus.NO_CONTENT, w);
|
||||
|
@ -127,13 +133,15 @@ class WorkbasketDefinitionControllerIntTest {
|
|||
|
||||
@Test
|
||||
void testImportWorkbasketWithDistributionTargetsInImportFile() throws IOException {
|
||||
List<WorkbasketDefinitionRepresentationModel> wbList =
|
||||
TaskanaPagedModel<WorkbasketDefinitionRepresentationModel> wbList =
|
||||
executeExportRequestForDomain("DOMAIN_A").getBody();
|
||||
assertThat(wbList).isNotNull();
|
||||
Iterator<WorkbasketDefinitionRepresentationModel> iterator = wbList.getContent().iterator();
|
||||
|
||||
WorkbasketDefinitionRepresentationModel w = wbList.get(0);
|
||||
WorkbasketDefinitionRepresentationModel w = iterator.next();
|
||||
w.setDistributionTargets(new HashSet<>());
|
||||
String letMeBeYourDistributionTarget = w.getWorkbasket().getWorkbasketId();
|
||||
WorkbasketDefinitionRepresentationModel w2 = wbList.get(1);
|
||||
WorkbasketDefinitionRepresentationModel w2 = iterator.next();
|
||||
w2.setDistributionTargets(Collections.singleton(letMeBeYourDistributionTarget));
|
||||
expectStatusWhenExecutingImportRequestOfWorkbaskets(HttpStatus.NO_CONTENT, w, w2);
|
||||
|
||||
|
@ -150,11 +158,14 @@ class WorkbasketDefinitionControllerIntTest {
|
|||
|
||||
@Test
|
||||
void testImportWorkbasketWithDistributionTargetsInSystem() throws IOException {
|
||||
List<WorkbasketDefinitionRepresentationModel> wbList =
|
||||
TaskanaPagedModel<WorkbasketDefinitionRepresentationModel> wbList =
|
||||
executeExportRequestForDomain("DOMAIN_A").getBody();
|
||||
|
||||
wbList.removeIf(definition -> definition.getDistributionTargets().isEmpty());
|
||||
WorkbasketDefinitionRepresentationModel w = wbList.get(0);
|
||||
assertThat(wbList).isNotNull();
|
||||
List<WorkbasketDefinitionRepresentationModel> content = new ArrayList<>(wbList.getContent());
|
||||
|
||||
content.removeIf(definition -> definition.getDistributionTargets().isEmpty());
|
||||
WorkbasketDefinitionRepresentationModel w = content.iterator().next();
|
||||
expectStatusWhenExecutingImportRequestOfWorkbaskets(HttpStatus.NO_CONTENT, w);
|
||||
|
||||
changeWorkbasketIdOrKey(w, null, "new");
|
||||
|
@ -163,50 +174,58 @@ class WorkbasketDefinitionControllerIntTest {
|
|||
|
||||
@Test
|
||||
void testImportWorkbasketWithDistributionTargetsNotInSystem() throws IOException {
|
||||
List<WorkbasketDefinitionRepresentationModel> wbList =
|
||||
TaskanaPagedModel<WorkbasketDefinitionRepresentationModel> wbList =
|
||||
executeExportRequestForDomain("DOMAIN_A").getBody();
|
||||
|
||||
WorkbasketDefinitionRepresentationModel w = wbList.get(0);
|
||||
assertThat(wbList).isNotNull();
|
||||
WorkbasketDefinitionRepresentationModel w = wbList.getContent().iterator().next();
|
||||
w.setDistributionTargets(Collections.singleton("invalidWorkbasketId"));
|
||||
try {
|
||||
expectStatusWhenExecutingImportRequestOfWorkbaskets(HttpStatus.BAD_REQUEST, w);
|
||||
fail("Expected http-Status 400");
|
||||
} catch (HttpClientErrorException e) {
|
||||
assertThat(e.getStatusCode()).isEqualTo(HttpStatus.BAD_REQUEST);
|
||||
}
|
||||
ThrowingCallable httpCall =
|
||||
() -> expectStatusWhenExecutingImportRequestOfWorkbaskets(HttpStatus.BAD_REQUEST, w);
|
||||
assertThatThrownBy(httpCall)
|
||||
.isInstanceOf(HttpClientErrorException.class)
|
||||
.extracting(e -> (HttpClientErrorException) e)
|
||||
.extracting(HttpStatusCodeException::getStatusCode)
|
||||
.isEqualTo(HttpStatus.BAD_REQUEST);
|
||||
|
||||
w.getWorkbasket().setKey("anotherNewKey");
|
||||
try {
|
||||
expectStatusWhenExecutingImportRequestOfWorkbaskets(HttpStatus.BAD_REQUEST, w);
|
||||
fail("Expected http-Status 400");
|
||||
} catch (HttpClientErrorException e) {
|
||||
assertThat(e.getStatusCode()).isEqualTo(HttpStatus.BAD_REQUEST);
|
||||
}
|
||||
|
||||
assertThatThrownBy(httpCall)
|
||||
.isInstanceOf(HttpClientErrorException.class)
|
||||
.extracting(e -> (HttpClientErrorException) e)
|
||||
.extracting(HttpStatusCodeException::getStatusCode)
|
||||
.isEqualTo(HttpStatus.BAD_REQUEST);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailOnImportDuplicates() throws IOException {
|
||||
WorkbasketDefinitionRepresentationModel w =
|
||||
executeExportRequestForDomain("DOMAIN_A").getBody().get(0);
|
||||
try {
|
||||
expectStatusWhenExecutingImportRequestOfWorkbaskets(HttpStatus.CONFLICT, w, w);
|
||||
fail("Expected http-Status 409");
|
||||
} catch (HttpClientErrorException e) {
|
||||
assertThat(e.getStatusCode()).isEqualTo(HttpStatus.CONFLICT);
|
||||
}
|
||||
TaskanaPagedModel<WorkbasketDefinitionRepresentationModel> pagedModel =
|
||||
executeExportRequestForDomain("DOMAIN_A").getBody();
|
||||
|
||||
assertThat(pagedModel).isNotNull();
|
||||
WorkbasketDefinitionRepresentationModel w = pagedModel.getContent().iterator().next();
|
||||
ThrowingCallable httpCall =
|
||||
() -> expectStatusWhenExecutingImportRequestOfWorkbaskets(HttpStatus.CONFLICT, w, w);
|
||||
assertThatThrownBy(httpCall)
|
||||
.isInstanceOf(HttpClientErrorException.class)
|
||||
.extracting(e -> (HttpClientErrorException) e)
|
||||
.extracting(HttpStatusCodeException::getStatusCode)
|
||||
.isEqualTo(HttpStatus.CONFLICT);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testNoErrorWhenImportWithSameIdButDifferentKeyAndDomain() throws IOException {
|
||||
List<WorkbasketDefinitionRepresentationModel> wbList =
|
||||
TaskanaPagedModel<WorkbasketDefinitionRepresentationModel> wbList =
|
||||
executeExportRequestForDomain("DOMAIN_A").getBody();
|
||||
|
||||
WorkbasketDefinitionRepresentationModel w = wbList.get(0);
|
||||
WorkbasketDefinitionRepresentationModel differentLogicalId = wbList.get(1);
|
||||
assertThat(wbList).isNotNull();
|
||||
Iterator<WorkbasketDefinitionRepresentationModel> iterator = wbList.getContent().iterator();
|
||||
WorkbasketDefinitionRepresentationModel w = iterator.next();
|
||||
WorkbasketDefinitionRepresentationModel differentLogicalId = iterator.next();
|
||||
this.changeWorkbasketIdOrKey(differentLogicalId, w.getWorkbasket().getWorkbasketId(), null);
|
||||
|
||||
// breaks the logic but not the script- should we really allow this case?
|
||||
WorkbasketDefinitionRepresentationModel theDestroyer = wbList.get(2);
|
||||
WorkbasketDefinitionRepresentationModel theDestroyer = iterator.next();
|
||||
theDestroyer.setDistributionTargets(
|
||||
Collections.singleton(differentLogicalId.getWorkbasket().getWorkbasketId()));
|
||||
|
||||
|
@ -216,16 +235,15 @@ class WorkbasketDefinitionControllerIntTest {
|
|||
|
||||
@Test
|
||||
void testErrorWhenImportWithSameAccessIdAndWorkbasket() {
|
||||
WorkbasketDefinitionRepresentationModel w =
|
||||
executeExportRequestForDomain("DOMAIN_A").getBody().get(0);
|
||||
TaskanaPagedModel<WorkbasketDefinitionRepresentationModel> pagedModel =
|
||||
executeExportRequestForDomain("DOMAIN_A").getBody();
|
||||
|
||||
assertThat(pagedModel).isNotNull();
|
||||
WorkbasketDefinitionRepresentationModel w = pagedModel.getContent().iterator().next();
|
||||
|
||||
String w1String = workbasketToString(w);
|
||||
w.getWorkbasket().setKey("new Key for this WB");
|
||||
String w2String = workbasketToString(w);
|
||||
ThrowingCallable httpCall =
|
||||
() -> {
|
||||
expectStatusWhenExecutingImportRequestOfWorkbaskets(
|
||||
HttpStatus.CONFLICT, Arrays.asList(w1String, w2String));
|
||||
expectStatusWhenExecutingImportRequestOfWorkbaskets(HttpStatus.CONFLICT, w, w);
|
||||
};
|
||||
assertThatThrownBy(httpCall).isInstanceOf(HttpClientErrorException.class);
|
||||
}
|
||||
|
@ -242,30 +260,33 @@ class WorkbasketDefinitionControllerIntTest {
|
|||
}
|
||||
}
|
||||
|
||||
private ResponseEntity<List<WorkbasketDefinitionRepresentationModel>>
|
||||
private ResponseEntity<TaskanaPagedModel<WorkbasketDefinitionRepresentationModel>>
|
||||
executeExportRequestForDomain(String domain) {
|
||||
return template.exchange(
|
||||
return TEMPLATE.exchange(
|
||||
restHelper.toUrl(Mapping.URL_WORKBASKETDEFIITIONS) + "?domain=" + domain,
|
||||
HttpMethod.GET,
|
||||
restHelper.defaultRequest(),
|
||||
new ParameterizedTypeReference<List<WorkbasketDefinitionRepresentationModel>>() {});
|
||||
new ParameterizedTypeReference<
|
||||
TaskanaPagedModel<WorkbasketDefinitionRepresentationModel>>() {});
|
||||
}
|
||||
|
||||
private void expectStatusWhenExecutingImportRequestOfWorkbaskets(
|
||||
HttpStatus expectedStatus, WorkbasketDefinitionRepresentationModel... workbaskets)
|
||||
throws IOException {
|
||||
List<String> workbasketStrings =
|
||||
Arrays.stream(workbaskets).map(this::workbasketToString).collect(Collectors.toList());
|
||||
expectStatusWhenExecutingImportRequestOfWorkbaskets(expectedStatus, workbasketStrings);
|
||||
TaskanaPagedModel<WorkbasketDefinitionRepresentationModel> pagedModel =
|
||||
new TaskanaPagedModel<>(
|
||||
TaskanaPagedModelKeys.WORKBASKET_DEFINITIONS, Arrays.asList(workbaskets));
|
||||
expectStatusWhenExecutingImportRequestOfWorkbaskets(expectedStatus, pagedModel);
|
||||
}
|
||||
|
||||
private void expectStatusWhenExecutingImportRequestOfWorkbaskets(
|
||||
HttpStatus expectedStatus, List<String> workbasketStrings) throws IOException {
|
||||
HttpStatus expectedStatus,
|
||||
TaskanaPagedModel<WorkbasketDefinitionRepresentationModel> pageModel)
|
||||
throws IOException {
|
||||
File tmpFile = File.createTempFile("test", ".tmp");
|
||||
OutputStreamWriter writer = new OutputStreamWriter(new FileOutputStream(tmpFile), UTF_8);
|
||||
writer.write(workbasketStrings.toString());
|
||||
writer.close();
|
||||
|
||||
try (OutputStreamWriter writer = new OutputStreamWriter(new FileOutputStream(tmpFile), UTF_8)) {
|
||||
objMapper.writeValue(writer, pageModel);
|
||||
}
|
||||
MultiValueMap<String, Object> body = new LinkedMultiValueMap<>();
|
||||
HttpHeaders headers = restHelper.getHeaders();
|
||||
headers.setContentType(MediaType.MULTIPART_FORM_DATA);
|
||||
|
@ -275,16 +296,7 @@ class WorkbasketDefinitionControllerIntTest {
|
|||
String serverUrl = restHelper.toUrl(Mapping.URL_WORKBASKETDEFIITIONS);
|
||||
|
||||
ResponseEntity<Void> responseImport =
|
||||
template.postForEntity(serverUrl, requestEntity, Void.class);
|
||||
TEMPLATE.postForEntity(serverUrl, requestEntity, Void.class);
|
||||
assertThat(responseImport.getStatusCode()).isEqualTo(expectedStatus);
|
||||
}
|
||||
|
||||
private String workbasketToString(
|
||||
WorkbasketDefinitionRepresentationModel workbasketDefinitionRepresentationModel) {
|
||||
try {
|
||||
return objMapper.writeValueAsString(workbasketDefinitionRepresentationModel);
|
||||
} catch (JsonProcessingException e) {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,8 +18,16 @@ import pro.taskana.workbasket.rest.models.WorkbasketRepresentationModel;
|
|||
@TaskanaSpringBootTest
|
||||
class WorkbasketRepresentationModelAssemblerTest {
|
||||
|
||||
@Autowired WorkbasketService workbasketService;
|
||||
@Autowired WorkbasketRepresentationModelAssembler workbasketRepresentationModelAssembler;
|
||||
private final WorkbasketService workbasketService;
|
||||
private final WorkbasketRepresentationModelAssembler workbasketRepresentationModelAssembler;
|
||||
|
||||
@Autowired
|
||||
WorkbasketRepresentationModelAssemblerTest(
|
||||
WorkbasketService workbasketService,
|
||||
WorkbasketRepresentationModelAssembler workbasketRepresentationModelAssembler) {
|
||||
this.workbasketService = workbasketService;
|
||||
this.workbasketRepresentationModelAssembler = workbasketRepresentationModelAssembler;
|
||||
}
|
||||
|
||||
@Test
|
||||
void workbasketToResource() {
|
||||
|
@ -53,7 +61,7 @@ class WorkbasketRepresentationModelAssemblerTest {
|
|||
// given
|
||||
WorkbasketRepresentationModel resource = new WorkbasketRepresentationModel();
|
||||
resource.setWorkbasketId("1");
|
||||
resource.setModified("2010-01-01T12:00:00Z");
|
||||
resource.setModified(Instant.parse("2010-01-01T12:00:00Z"));
|
||||
resource.setType(WorkbasketType.PERSONAL);
|
||||
// when
|
||||
Workbasket workbasket = workbasketRepresentationModelAssembler.toEntityModel(resource);
|
||||
|
@ -66,7 +74,7 @@ class WorkbasketRepresentationModelAssemblerTest {
|
|||
// given
|
||||
WorkbasketRepresentationModel resource = new WorkbasketRepresentationModel();
|
||||
resource.setWorkbasketId("1");
|
||||
resource.setCreated("2010-01-01T12:00:00Z");
|
||||
resource.setCreated(Instant.parse("2010-01-01T12:00:00Z"));
|
||||
resource.setType(WorkbasketType.PERSONAL);
|
||||
// when
|
||||
Workbasket workbasket = workbasketRepresentationModelAssembler.toEntityModel(resource);
|
||||
|
@ -80,8 +88,8 @@ class WorkbasketRepresentationModelAssemblerTest {
|
|||
WorkbasketRepresentationModel workbasketRepresentationModel =
|
||||
new WorkbasketRepresentationModel();
|
||||
workbasketRepresentationModel.setWorkbasketId("1");
|
||||
workbasketRepresentationModel.setCreated("2010-01-01T12:00:00Z");
|
||||
workbasketRepresentationModel.setModified("2010-01-01T12:00:00Z");
|
||||
workbasketRepresentationModel.setCreated(Instant.parse("2010-01-01T12:00:00Z"));
|
||||
workbasketRepresentationModel.setModified(Instant.parse("2010-01-01T12:00:00Z"));
|
||||
workbasketRepresentationModel.setCustom1("Custom1");
|
||||
workbasketRepresentationModel.setCustom2("Custom2");
|
||||
workbasketRepresentationModel.setCustom3("Custom3");
|
||||
|
@ -124,9 +132,9 @@ class WorkbasketRepresentationModelAssemblerTest {
|
|||
assertThat(workbasketRepresentationModel.getWorkbasketId()).isEqualTo(workbasket.getId());
|
||||
assertThat(workbasketRepresentationModel.getKey()).isEqualTo(workbasket.getKey());
|
||||
assertThat(workbasketRepresentationModel.getCreated())
|
||||
.isEqualTo(workbasket.getCreated() == null ? null : workbasket.getCreated().toString());
|
||||
.isEqualTo(workbasket.getCreated());
|
||||
assertThat(workbasketRepresentationModel.getModified())
|
||||
.isEqualTo(workbasket.getModified() == null ? null : workbasket.getModified().toString());
|
||||
.isEqualTo(workbasket.getModified());
|
||||
assertThat(workbasketRepresentationModel.getName()).isEqualTo(workbasket.getName());
|
||||
assertThat(workbasketRepresentationModel.getDescription())
|
||||
.isEqualTo(workbasket.getDescription());
|
||||
|
|
Loading…
Reference in New Issue