From 4f45dfd5d6350f6e9bb36eee4d30dcac82b4862c Mon Sep 17 00:00:00 2001 From: CRoberto1926 <3205022+CRoberto1926@users.noreply.github.com> Date: Thu, 25 Jul 2024 13:12:09 +0200 Subject: [PATCH] Closes #2635: Make owner-is-null=owner-is-null not valid, allow use case "owner-is-null=true" --- .../rest/util/QueryParamsValidator.java | 65 ++++++++++---- .../pro/taskana/task/rest/TaskController.java | 7 ++ .../task/rest/TaskQueryFilterParameter.java | 43 ++++++++- .../pro/taskana/user/rest/UserController.java | 5 +- .../task/rest/TaskControllerIntTest.java | 51 ++++++----- .../user/rest/UserControllerIntTest.java | 87 ++++++++++--------- 6 files changed, 175 insertions(+), 83 deletions(-) diff --git a/rest/taskana-rest-spring/src/main/java/pro/taskana/common/rest/util/QueryParamsValidator.java b/rest/taskana-rest-spring/src/main/java/pro/taskana/common/rest/util/QueryParamsValidator.java index 8f3c61a7c..21a9ded43 100644 --- a/rest/taskana-rest-spring/src/main/java/pro/taskana/common/rest/util/QueryParamsValidator.java +++ b/rest/taskana-rest-spring/src/main/java/pro/taskana/common/rest/util/QueryParamsValidator.java @@ -2,14 +2,13 @@ package pro.taskana.common.rest.util; import com.fasterxml.jackson.annotation.JsonProperty; import jakarta.servlet.http.HttpServletRequest; +import java.util.Arrays; import java.util.HashSet; +import java.util.Map; import java.util.Optional; import java.util.Set; -import java.util.regex.Matcher; -import java.util.regex.Pattern; import java.util.stream.Collectors; import java.util.stream.Stream; -import pro.taskana.common.api.exceptions.InvalidArgumentException; public class QueryParamsValidator { @@ -35,21 +34,57 @@ public class QueryParamsValidator { if (!providedParams.isEmpty()) { throw new IllegalArgumentException("Unknown request parameters found: " + providedParams); } - checkExactParam(request, "owner-is-null"); } - public static void checkExactParam(HttpServletRequest request, String queryParameter) { - String queryString = request.getQueryString(); - boolean containParam = queryString != null && queryString.contains(queryParameter); - if (containParam) { - Pattern pattern = Pattern.compile("\\b" + queryParameter + "(&|$)"); - Matcher matcher = pattern.matcher(queryString); + public static boolean hasQueryParameterValues(HttpServletRequest request, String queryParameter) { - boolean hasExactParam = matcher.find(); - if (!hasExactParam) { - throw new InvalidArgumentException( - "It is prohibited to use the param " + queryParameter + " with values."); - } + Map queryParametersMap = request.getParameterMap(); + + if (queryParametersMap.isEmpty()) { + return false; } + + String[] queryParameterValues = queryParametersMap.get(queryParameter); + + if (queryParameterValues == null) { + return false; + } + + boolean hasQueryParameterNotEmptyValues = + Arrays.stream(queryParameterValues).anyMatch(value -> !value.isBlank()); + + /* Workaround to manage the case "query-param=". + It should be safe enough to use because we have checked all other possibilities before. */ + boolean hasQueryParameterEmptyValues = request.getQueryString().contains(queryParameter + "="); + + return hasQueryParameterNotEmptyValues || hasQueryParameterEmptyValues; + } + + public static boolean hasQueryParameterValuesOrIsNotTrue( + HttpServletRequest request, String queryParameter) { + + Map queryParametersMap = request.getParameterMap(); + + if (queryParametersMap.isEmpty()) { + return false; + } + + String[] queryParameterValues = queryParametersMap.get(queryParameter); + + if (queryParameterValues == null) { + return false; + } + + boolean hasQueryParameterProhibitedValues = + Arrays.stream(queryParameterValues) + .anyMatch(value -> !value.isBlank() && !Boolean.parseBoolean(value)); + + /* Workaround to manage the case "query-param=". + It should be safe enough to use because we have checked all other possibilities before. */ + boolean hasQueryParameterEmptyValues = + Arrays.stream(queryParameterValues).allMatch(String::isBlank) + && request.getQueryString().contains(queryParameter + "="); + + return hasQueryParameterProhibitedValues || hasQueryParameterEmptyValues; } } diff --git a/rest/taskana-rest-spring/src/main/java/pro/taskana/task/rest/TaskController.java b/rest/taskana-rest-spring/src/main/java/pro/taskana/task/rest/TaskController.java index 69aa22f24..91a73280c 100644 --- a/rest/taskana-rest-spring/src/main/java/pro/taskana/task/rest/TaskController.java +++ b/rest/taskana-rest-spring/src/main/java/pro/taskana/task/rest/TaskController.java @@ -139,6 +139,7 @@ public class TaskController { * @param sortParameter the sort parameters * @param pagingParameter the paging parameters * @return the Tasks with the given filter, sort and paging options. + * @throws InvalidArgumentException if the query parameter "owner-is-null" has values */ @GetMapping(path = RestEndpoints.URL_TASKS) @Transactional(readOnly = true, rollbackFor = Exception.class) @@ -158,6 +159,12 @@ public class TaskController { TaskQueryGroupByParameter.class, QuerySortParameter.class, QueryPagingParameter.class); + + if (QueryParamsValidator.hasQueryParameterValuesOrIsNotTrue(request, "owner-is-null")) { + throw new InvalidArgumentException( + "It is prohibited to use the param owner-is-null with values."); + } + TaskQuery query = taskService.createTaskQuery(); filterParameter.apply(query); diff --git a/rest/taskana-rest-spring/src/main/java/pro/taskana/task/rest/TaskQueryFilterParameter.java b/rest/taskana-rest-spring/src/main/java/pro/taskana/task/rest/TaskQueryFilterParameter.java index c1af19acb..7a3b7be3e 100644 --- a/rest/taskana-rest-spring/src/main/java/pro/taskana/task/rest/TaskQueryFilterParameter.java +++ b/rest/taskana-rest-spring/src/main/java/pro/taskana/task/rest/TaskQueryFilterParameter.java @@ -28,6 +28,7 @@ public class TaskQueryFilterParameter implements QueryParameter /** Filter by what the task id shouldn't be. This is an exact match. */ @JsonProperty("task-id-not") private final String[] taskIdNotIn; + // endregion // region externalId /** Filter by the external id of the Task. This is an exact match. */ @@ -37,6 +38,7 @@ public class TaskQueryFilterParameter implements QueryParameter /** Filter by what the external id of the Task shouldn't be. This is an exact match. */ @JsonProperty("external-id-not") private final String[] externalIdNotIn; + // endregion // region received /** @@ -101,6 +103,7 @@ public class TaskQueryFilterParameter implements QueryParameter */ @JsonProperty("received-until-not") private final Instant receivedUntilNot; + // endregion // region created /** @@ -164,6 +167,7 @@ public class TaskQueryFilterParameter implements QueryParameter */ @JsonProperty("created-until-not") private final Instant createdUntilNot; + // endregion // region claimed /** @@ -183,6 +187,7 @@ public class TaskQueryFilterParameter implements QueryParameter */ @JsonProperty("claimed-not") private final Instant[] claimedNotWithin; + // endregion // region modified /** @@ -202,6 +207,7 @@ public class TaskQueryFilterParameter implements QueryParameter */ @JsonProperty("modified-not") private final Instant[] modifiedNotWithin; + // endregion // region planned /** @@ -265,6 +271,7 @@ public class TaskQueryFilterParameter implements QueryParameter */ @JsonProperty("planned-until-not") private final Instant plannedUntilNot; + // endregion // region due /** @@ -328,6 +335,7 @@ public class TaskQueryFilterParameter implements QueryParameter */ @JsonProperty("due-until-not") private final Instant dueUntilNot; + // endregion // region completed /** @@ -392,6 +400,7 @@ public class TaskQueryFilterParameter implements QueryParameter */ @JsonProperty("completed-until-not") private final Instant completedUntilNot; + // endregion // region name /** Filter by the name of the Task. This is an exact match. */ @@ -417,6 +426,7 @@ public class TaskQueryFilterParameter implements QueryParameter */ @JsonProperty("name-not-like") private final String[] nameNotLike; + // endregion // region creator /** Filter by creator of the Task. This is an exact match. */ @@ -442,6 +452,7 @@ public class TaskQueryFilterParameter implements QueryParameter */ @JsonProperty("creator-not-like") private final String[] creatorNotLike; + // endregion // region note /** @@ -459,6 +470,7 @@ public class TaskQueryFilterParameter implements QueryParameter */ @JsonProperty("note-not-like") private final String[] noteNotLike; + // endregion // region description /** @@ -476,6 +488,7 @@ public class TaskQueryFilterParameter implements QueryParameter */ @JsonProperty("description-not-like") private final String[] descriptionNotLike; + // endregion // region priority /** Filter by the priority of the Task. This is an exact match. */ @@ -509,6 +522,7 @@ public class TaskQueryFilterParameter implements QueryParameter /** Filter by excluding priority up to the given value (inclusive). */ @JsonProperty("priority-not-until") private final Integer priorityNotUntil; + // endregion // region state /** Filter by the Task state. This is an exact match. */ @@ -518,6 +532,7 @@ public class TaskQueryFilterParameter implements QueryParameter /** Filter by what the Task state shouldn't be. This is an exact match. */ @JsonProperty("state-not") private final TaskState[] stateNotIn; + // endregion // region classificationId /** Filter by the classification id of the Task. This is an exact match. */ @@ -527,6 +542,7 @@ public class TaskQueryFilterParameter implements QueryParameter /** Filter by what the classification id of the Task shouldn't be. This is an exact match. */ @JsonProperty("classification-id-not") private final String[] classificationIdNotIn; + // endregion // region classificationKey /** Filter by the classification key of the Task. This is an exact match. */ @@ -552,6 +568,7 @@ public class TaskQueryFilterParameter implements QueryParameter */ @JsonProperty("classification-key-not-like") private final String[] classificationKeyNotLike; + // endregion // region classificationParentKey /** @@ -583,6 +600,7 @@ public class TaskQueryFilterParameter implements QueryParameter */ @JsonProperty("classification-parent-key-not-like") private final String[] classificationParentKeyNotLike; + // endregion // region classificationCategory /** Filter by the classification category of the Task. This is an exact match. */ @@ -610,6 +628,7 @@ public class TaskQueryFilterParameter implements QueryParameter */ @JsonProperty("classification-category-not-like") private final String[] classificationCategoryNotLike; + // endregion // region classificationName /** Filter by the classification name of the Task. This is an exact match. */ @@ -635,6 +654,7 @@ public class TaskQueryFilterParameter implements QueryParameter */ @JsonProperty("classification-name-not-like") private final String[] classificationNameNotLike; + // endregion // region workbasketId /** Filter by workbasket id of the Task. This is an exact match. */ @@ -644,6 +664,7 @@ public class TaskQueryFilterParameter implements QueryParameter /** Filter by what the workbasket id of the Task shouldn't be. This is an exact match. */ @JsonProperty("workbasket-id-not") private final String[] workbasketIdNotIn; + // endregion // region workbasketKeyDomain /** @@ -663,6 +684,7 @@ public class TaskQueryFilterParameter implements QueryParameter /** Filter by domain of the Task. This is an exact match. */ @JsonProperty("domain") private final String domain; + // endregion // region businessProcessId /** Filter by the business process id of the Task. This is an exact match. */ @@ -749,6 +771,7 @@ public class TaskQueryFilterParameter implements QueryParameter */ @JsonProperty("owner-is-null") private final String ownerNull; + // endregion // region primaryObjectReference /** @@ -759,6 +782,7 @@ public class TaskQueryFilterParameter implements QueryParameter */ @JsonProperty("por") private final ObjectReference[] primaryObjectReferenceIn; + // endregion // region primaryObjectReferenceCompany /** Filter by the company of the primary object reference of the Task. This is an exact match. */ @@ -787,6 +811,7 @@ public class TaskQueryFilterParameter implements QueryParameter */ @JsonProperty("por-company-not-like") private final String[] porCompanyNotLike; + // endregion // region primaryObjectReferenceSystem /** Filter by the system of the primary object reference of the Task. This is an exact match. */ @@ -815,6 +840,7 @@ public class TaskQueryFilterParameter implements QueryParameter */ @JsonProperty("por-system-not-like") private final String[] porSystemNotLike; + // endregion // region primaryObjectReferenceSystemInstance /** @@ -846,6 +872,7 @@ public class TaskQueryFilterParameter implements QueryParameter */ @JsonProperty("por-instance-not-like") private final String[] porInstanceNotLike; + // endregion // region primaryObjectReferenceSystemType /** Filter by the type of the primary object reference of the Task. This is an exact match. */ @@ -874,6 +901,7 @@ public class TaskQueryFilterParameter implements QueryParameter */ @JsonProperty("por-type-not-like") private final String[] porTypeNotLike; + // endregion // region primaryObjectReferenceSystemValue /** Filter by the value of the primary object reference of the Task. This is an exact match. */ @@ -902,6 +930,7 @@ public class TaskQueryFilterParameter implements QueryParameter */ @JsonProperty("por-value-not-like") private final String[] porValueNotLike; + // endregion // region secondaryObjectReference /** @@ -912,6 +941,7 @@ public class TaskQueryFilterParameter implements QueryParameter */ @JsonProperty("sor") private final ObjectReference[] secondaryObjectReferenceIn; + // endregion // region secondaryObjectReferenceCompany /** @@ -992,11 +1022,13 @@ public class TaskQueryFilterParameter implements QueryParameter /** Filter by the is read flag of the Task. This is an exact match. */ @JsonProperty("is-read") private final Boolean isRead; + // endregion // region transferred /** Filter by the is transferred flag of the Task. This is an exact match. */ @JsonProperty("is-transferred") private final Boolean isTransferred; + // endregion // region attachmentClassificationId /** Filter by the attachment classification id of the Task. This is an exact match. */ @@ -1009,6 +1041,7 @@ public class TaskQueryFilterParameter implements QueryParameter */ @JsonProperty("attachment-classification-id-not") private final String[] attachmentClassificationIdNotIn; + // endregion // region attachmentClassificationKey /** Filter by the attachment classification key of the Task. This is an exact match. */ @@ -1037,6 +1070,7 @@ public class TaskQueryFilterParameter implements QueryParameter */ @JsonProperty("attachment-classification-key-not-like") private final String[] attachmentClassificationKeyNotLike; + // endregion // region attachmentClassificationName /** Filter by the attachment classification name of the Task. This is an exact match. */ @@ -1065,6 +1099,7 @@ public class TaskQueryFilterParameter implements QueryParameter */ @JsonProperty("attachment-classification-name-not-like") private final String[] attachmentClassificationNameNotLike; + // endregion // region attachmentChannel /** Filter by the attachment channel of the Task. This is an exact match. */ @@ -1090,6 +1125,7 @@ public class TaskQueryFilterParameter implements QueryParameter */ @JsonProperty("attachment-channel-not-like") private final String[] attachmentChannelNotLike; + // endregion // region attachmentReferenceValue /** Filter by the attachment reference of the Task. This is an exact match. */ @@ -1115,6 +1151,7 @@ public class TaskQueryFilterParameter implements QueryParameter */ @JsonProperty("attachment-reference-not-like") private final String[] attachmentReferenceNotLike; + // endregion // region attachmentReceived /** @@ -1134,6 +1171,7 @@ public class TaskQueryFilterParameter implements QueryParameter */ @JsonProperty("attachment-received-not") private final Instant[] attachmentReceivedNotWithin; + // endregion // region withoutAttachment /** @@ -1142,6 +1180,7 @@ public class TaskQueryFilterParameter implements QueryParameter */ @JsonProperty("without-attachment") private final Boolean withoutAttachment; + // endregion // region callbackState /** Filter by the callback state of the Task. This is an exact match. */ @@ -1151,6 +1190,7 @@ public class TaskQueryFilterParameter implements QueryParameter /** Filter by what the callback state of the Task shouldn't be. This is an exact match. */ @JsonProperty("callback-state-not") private final CallbackState[] callbackStateNotIn; + // endregion // region wildcardSearchValue /** @@ -1168,6 +1208,7 @@ public class TaskQueryFilterParameter implements QueryParameter */ @JsonProperty("wildcard-search-value") private final String wildcardSearchValue; + // endregion // region constructor @@ -2203,7 +2244,7 @@ public class TaskQueryFilterParameter implements QueryParameter return this.ownerIn; } if (this.ownerIn == null) { - return new String[]{null}; + return new String[] {null}; } List ownerInAsList = new ArrayList<>(Arrays.asList(this.ownerIn)); ownerInAsList.add(null); diff --git a/rest/taskana-rest-spring/src/main/java/pro/taskana/user/rest/UserController.java b/rest/taskana-rest-spring/src/main/java/pro/taskana/user/rest/UserController.java index e380f3c9e..50ce03bae 100644 --- a/rest/taskana-rest-spring/src/main/java/pro/taskana/user/rest/UserController.java +++ b/rest/taskana-rest-spring/src/main/java/pro/taskana/user/rest/UserController.java @@ -94,7 +94,10 @@ public class UserController { } if (currentUser != null) { - QueryParamsValidator.checkExactParam(request, "current-user"); + if (QueryParamsValidator.hasQueryParameterValues(request, "current-user")) { + throw new InvalidArgumentException( + "It is prohibited to use the param current-user with values."); + } users.add(userService.getUser(this.currentUserContext.getUserid())); } diff --git a/rest/taskana-rest-spring/src/test/java/pro/taskana/task/rest/TaskControllerIntTest.java b/rest/taskana-rest-spring/src/test/java/pro/taskana/task/rest/TaskControllerIntTest.java index 3f964d507..d81b90e61 100644 --- a/rest/taskana-rest-spring/src/test/java/pro/taskana/task/rest/TaskControllerIntTest.java +++ b/rest/taskana-rest-spring/src/test/java/pro/taskana/task/rest/TaskControllerIntTest.java @@ -61,7 +61,6 @@ import pro.taskana.workbasket.rest.models.WorkbasketSummaryRepresentationModel; @TaskanaSpringBootTest class TaskControllerIntTest { - @Autowired TaskanaConfiguration taskanaConfiguration; private static final ParameterizedTypeReference TASK_SUMMARY_PAGE_MODEL_TYPE = new ParameterizedTypeReference<>() {}; private static final ParameterizedTypeReference @@ -71,6 +70,7 @@ class TaskControllerIntTest { private final RestHelper restHelper; private final DataSource dataSource; private final String schemaName; + @Autowired TaskanaConfiguration taskanaConfiguration; @Autowired TaskControllerIntTest( @@ -149,16 +149,16 @@ class TaskControllerIntTest { private AttachmentRepresentationModel getAttachmentResourceSample() { AttachmentRepresentationModel attachmentRepresentationModel = - new AttachmentRepresentationModel(); + new AttachmentRepresentationModel(); attachmentRepresentationModel.setAttachmentId("A11010"); attachmentRepresentationModel.setObjectReference(getObjectReferenceResourceSample()); ClassificationSummaryRepresentationModel classificationSummaryRepresentationModel = - new ClassificationSummaryRepresentationModel(); - classificationSummaryRepresentationModel - .setClassificationId("CLI:100000000000000000000000000000000004"); + new ClassificationSummaryRepresentationModel(); + classificationSummaryRepresentationModel.setClassificationId( + "CLI:100000000000000000000000000000000004"); classificationSummaryRepresentationModel.setKey("L11010"); - attachmentRepresentationModel - .setClassificationSummary(classificationSummaryRepresentationModel); + attachmentRepresentationModel.setClassificationSummary( + classificationSummaryRepresentationModel); return attachmentRepresentationModel; } @@ -1195,8 +1195,11 @@ class TaskControllerIntTest { @CsvSource({ "owner=user-1-1, 10", "owner-is-null, 65", + "owner-is-null=true, 65", "owner-is-null&owner=user-1-1, 75", + "owner-is-null=TRUE&owner=user-1-1, 75", "state=READY&owner-is-null&owner=user-1-1, 56", + "state=READY&owner-is-null=TrUe&owner=user-1-1, 56", }) void should_ReturnTasksWithVariousOwnerParameters_When_GettingTasks( String queryParams, int expectedSize) { @@ -1215,7 +1218,9 @@ class TaskControllerIntTest { List> list = List.of( Pair.of("When owner-is-null=", "?owner-is-null="), - Pair.of("When owner-is-null=anyValue", "?owner-is-null=anyValue1,anyValue2")); + Pair.of("When owner-is-null=owner-is-null", "?owner-is-null=owner-is-null"), + Pair.of( + "When owner-is-null=anyValue1,anyValue2", "?owner-is-null=anyValue1,anyValue2")); ThrowingConsumer> testOwnerIsNull = t -> { String url = restHelper.toUrl(RestEndpoints.URL_TASKS) + t.getRight(); @@ -1550,16 +1555,16 @@ class TaskControllerIntTest { String url = restHelper.toUrl(RestEndpoints.URL_TASKS); HttpEntity auth = - new HttpEntity<>( - taskRepresentationModel, RestHelper.generateHeadersForUser("teamlead-1")); + new HttpEntity<>( + taskRepresentationModel, RestHelper.generateHeadersForUser("teamlead-1")); ThrowingCallable httpCall = - () -> TEMPLATE.exchange(url, HttpMethod.POST, auth, TASK_MODEL_TYPE); + () -> TEMPLATE.exchange(url, HttpMethod.POST, auth, TASK_MODEL_TYPE); assertThatThrownBy(httpCall) - .extracting(HttpStatusCodeException.class::cast) - .extracting(HttpStatusCodeException::getStatusCode) - .isEqualTo(HttpStatus.BAD_REQUEST); + .extracting(HttpStatusCodeException.class::cast) + .extracting(HttpStatusCodeException::getStatusCode) + .isEqualTo(HttpStatus.BAD_REQUEST); } @Test @@ -1789,13 +1794,12 @@ class TaskControllerIntTest { @Test void should_ThrowError_When_UpdatingTaskWithBadAttachment() { String url = - restHelper.toUrl(RestEndpoints.URL_TASKS_ID, - "TKI:100000000000000000000000000000000000"); + restHelper.toUrl(RestEndpoints.URL_TASKS_ID, "TKI:100000000000000000000000000000000000"); HttpEntity httpEntityWithoutBody = - new HttpEntity<>(RestHelper.generateHeadersForUser("teamlead-1")); + new HttpEntity<>(RestHelper.generateHeadersForUser("teamlead-1")); ResponseEntity responseGet = - TEMPLATE.exchange(url, HttpMethod.GET, httpEntityWithoutBody, TASK_MODEL_TYPE); + TEMPLATE.exchange(url, HttpMethod.GET, httpEntityWithoutBody, TASK_MODEL_TYPE); final TaskRepresentationModel originalTask = responseGet.getBody(); @@ -1803,17 +1807,16 @@ class TaskControllerIntTest { attachmentRepresentationModel.setTaskId(originalTask.getTaskId() + "wrongId"); originalTask.setAttachments(Lists.newArrayList(attachmentRepresentationModel)); - HttpEntity httpEntity = - new HttpEntity<>(originalTask, RestHelper.generateHeadersForUser("teamlead-1")); + new HttpEntity<>(originalTask, RestHelper.generateHeadersForUser("teamlead-1")); ThrowingCallable httpCall = - () -> TEMPLATE.exchange(url, HttpMethod.PUT, httpEntity, TASK_MODEL_TYPE); + () -> TEMPLATE.exchange(url, HttpMethod.PUT, httpEntity, TASK_MODEL_TYPE); assertThatThrownBy(httpCall) - .extracting(HttpStatusCodeException.class::cast) - .extracting(HttpStatusCodeException::getStatusCode) - .isEqualTo(HttpStatus.BAD_REQUEST); + .extracting(HttpStatusCodeException.class::cast) + .extracting(HttpStatusCodeException::getStatusCode) + .isEqualTo(HttpStatus.BAD_REQUEST); } } diff --git a/rest/taskana-rest-spring/src/test/java/pro/taskana/user/rest/UserControllerIntTest.java b/rest/taskana-rest-spring/src/test/java/pro/taskana/user/rest/UserControllerIntTest.java index 9ef02b3c3..49fe318a1 100644 --- a/rest/taskana-rest-spring/src/test/java/pro/taskana/user/rest/UserControllerIntTest.java +++ b/rest/taskana-rest-spring/src/test/java/pro/taskana/user/rest/UserControllerIntTest.java @@ -31,7 +31,7 @@ class UserControllerIntTest { } @Test - void should_ReturnExistingUser() throws Exception { + void should_ReturnExistingUser() { String url = restHelper.toUrl(RestEndpoints.URL_USERS_ID, "TEAMLEAD-1"); HttpEntity auth = new HttpEntity<>(RestHelper.generateHeadersForUser("teamlead-1")); @@ -45,7 +45,7 @@ class UserControllerIntTest { } @Test - void should_ReturnExistingUsers() throws Exception { + void should_ReturnExistingUsers() { String url = restHelper.toUrl(RestEndpoints.URL_USERS) + "?user-id=user-1-1&user-id=USER-1-2"; HttpEntity auth = new HttpEntity<>(RestHelper.generateHeadersForUser("teamlead-1")); @@ -69,11 +69,11 @@ class UserControllerIntTest { HttpEntity auth = new HttpEntity<>(RestHelper.generateHeadersForUser("teamlead-1")); ResponseEntity response = - TEMPLATE.exchange( - url, - HttpMethod.GET, - auth, - ParameterizedTypeReference.forType(UserCollectionRepresentationModel.class)); + TEMPLATE.exchange( + url, + HttpMethod.GET, + auth, + ParameterizedTypeReference.forType(UserCollectionRepresentationModel.class)); assertThat(response.getBody()).isNotNull(); assertThat(response.getBody().getContent()).hasSize(1); assertThat(response.getBody().getContent()).extracting("userId").containsExactly("teamlead-1"); @@ -85,16 +85,17 @@ class UserControllerIntTest { HttpEntity auth = new HttpEntity<>(RestHelper.generateHeadersForUser("teamlead-1")); ThrowingCallable httpCall = - () -> TEMPLATE.exchange( - url, - HttpMethod.GET, - auth, - ParameterizedTypeReference.forType(UserCollectionRepresentationModel.class)); + () -> + TEMPLATE.exchange( + url, + HttpMethod.GET, + auth, + ParameterizedTypeReference.forType(UserCollectionRepresentationModel.class)); assertThatThrownBy(httpCall) - .isInstanceOf(HttpStatusCodeException.class) - .extracting(HttpStatusCodeException.class::cast) - .extracting(HttpStatusCodeException::getStatusCode) - .isEqualTo(HttpStatus.BAD_REQUEST); + .isInstanceOf(HttpStatusCodeException.class) + .extracting(HttpStatusCodeException.class::cast) + .extracting(HttpStatusCodeException::getStatusCode) + .isEqualTo(HttpStatus.BAD_REQUEST); } @Test @@ -103,16 +104,17 @@ class UserControllerIntTest { HttpEntity auth = new HttpEntity<>(RestHelper.generateHeadersForUser("teamlead-1")); ThrowingCallable httpCall = - () -> TEMPLATE.exchange( - url, - HttpMethod.GET, - auth, - ParameterizedTypeReference.forType(UserCollectionRepresentationModel.class)); + () -> + TEMPLATE.exchange( + url, + HttpMethod.GET, + auth, + ParameterizedTypeReference.forType(UserCollectionRepresentationModel.class)); assertThatThrownBy(httpCall) - .isInstanceOf(HttpStatusCodeException.class) - .extracting(HttpStatusCodeException.class::cast) - .extracting(HttpStatusCodeException::getStatusCode) - .isEqualTo(HttpStatus.BAD_REQUEST); + .isInstanceOf(HttpStatusCodeException.class) + .extracting(HttpStatusCodeException.class::cast) + .extracting(HttpStatusCodeException::getStatusCode) + .isEqualTo(HttpStatus.BAD_REQUEST); } @Test @@ -121,38 +123,39 @@ class UserControllerIntTest { HttpEntity auth = new HttpEntity<>(RestHelper.generateHeadersForUser("teamlead-1")); ResponseEntity response = - TEMPLATE.exchange( - url, - HttpMethod.GET, - auth, - ParameterizedTypeReference.forType(UserCollectionRepresentationModel.class)); + TEMPLATE.exchange( + url, + HttpMethod.GET, + auth, + ParameterizedTypeReference.forType(UserCollectionRepresentationModel.class)); assertThat(response.getBody()).isNotNull(); assertThat(response.getBody().getContent()).hasSize(1); assertThat(response.getBody().getContent()).extracting("userId").containsExactly("teamlead-1"); } @Test - void should_ReturnExistingUsersAndCurrentUser() throws Exception { - String url = restHelper.toUrl(RestEndpoints.URL_USERS) + void should_ReturnExistingUsersAndCurrentUser() { + String url = + restHelper.toUrl(RestEndpoints.URL_USERS) + "?user-id=user-1-1&user-id=USER-1-2¤t-user"; HttpEntity auth = new HttpEntity<>(RestHelper.generateHeadersForUser("teamlead-1")); ResponseEntity responseEntity = - TEMPLATE.exchange( - url, - HttpMethod.GET, - auth, - ParameterizedTypeReference.forType(UserCollectionRepresentationModel.class)); + TEMPLATE.exchange( + url, + HttpMethod.GET, + auth, + ParameterizedTypeReference.forType(UserCollectionRepresentationModel.class)); UserCollectionRepresentationModel response = responseEntity.getBody(); assertThat(response).isNotNull(); assertThat(response.getContent()).hasSize(3); assertThat(response.getContent()) - .extracting("userId") - .containsExactlyInAnyOrder("user-1-1", "user-1-2", "teamlead-1"); + .extracting("userId") + .containsExactlyInAnyOrder("user-1-1", "user-1-2", "teamlead-1"); } @Test - void should_ReturnExistingUsers_When_ParameterContainsDuplicateAndInvalidIds() throws Exception { + void should_ReturnExistingUsers_When_ParameterContainsDuplicateAndInvalidIds() { // also testing different query parameter format String url = restHelper.toUrl(RestEndpoints.URL_USERS) @@ -180,7 +183,7 @@ class UserControllerIntTest { } @Test - void should_CreateValidUser_When_CallingCreateEndpoint() throws Exception { + void should_CreateValidUser_When_CallingCreateEndpoint() { UserRepresentationModel newUser = new UserRepresentationModel(); newUser.setUserId("12345"); newUser.setGroups(Set.of("group1", "group2")); @@ -217,7 +220,7 @@ class UserControllerIntTest { } @Test - void should_UpdateExistingUser_When_CallingUpdateEndpoint() throws Exception { + void should_UpdateExistingUser_When_CallingUpdateEndpoint() { String url = restHelper.toUrl(RestEndpoints.URL_USERS_ID, "teamlead-1"); HttpEntity auth = new HttpEntity<>(RestHelper.generateHeadersForUser("teamlead-1"));