Repository: holunda-io/camunda-bpm-taskpool (kotlin)

Issue:
Polyflow JPA view: Sort ignores direction
### Steps to reproduce

1. Adding direction order check to SpecificationTest#'creates a paged request'
1. Running test

* camunda-bpm-taskpool version: latest
* Camunda BPM version: -
* JDK version:  11
* Operating system: Windows 10
* Complete executable reproducer: merge request follows directly
* Steps: -

### Expected behaviour
first char '+' should return a ascending result
first char '-' should return a descending result

### Actual behaviour

default sort direction of JPA is used ignoring first char. 
Internally it throws an IllegalArgumentException in Sort.Direction.fromString

(In case of exceptions provide full stack trace)

Pull request description:

Patch:
diff --git a/view/jpa/src/main/kotlin/io/holunda/polyflow/view/jpa/SpecificationExt.kt b/view/jpa/src/main/kotlin/io/holunda/polyflow/view/jpa/SpecificationExt.kt
index 8cb6747b1..5c4db77d7 100644
--- a/view/jpa/src/main/kotlin/io/holunda/polyflow/view/jpa/SpecificationExt.kt
+++ b/view/jpa/src/main/kotlin/io/holunda/polyflow/view/jpa/SpecificationExt.kt
@@ -21,6 +21,7 @@ import io.holunda.polyflow.view.jpa.task.TaskRepository.Companion.likeDescriptio
 import io.holunda.polyflow.view.jpa.task.TaskRepository.Companion.likeName
 import org.springframework.data.domain.PageRequest
 import org.springframework.data.domain.Sort
+import org.springframework.data.domain.Sort.Direction
 import org.springframework.data.jpa.domain.Specification
 import org.springframework.data.jpa.domain.Specification.where
 
@@ -66,7 +67,8 @@ fun pageRequest(page: Int, size: Int, sort: String?): PageRequest {
   val sortCriteria = if (sort.isNullOrBlank()) {
     null
   } else {
-    Sort.by(Sort.Direction.fromOptionalString(sort.substring(0, 1)).orElse(Sort.DEFAULT_DIRECTION), sort.substring(1))
+    val direction = if(sort.substring(0, 1) == "+") Direction.ASC else Direction.DESC
+    Sort.by(direction, sort.substring(1))
   }
   return if (sortCriteria != null) {
     PageRequest.of(page, size, sortCriteria)


Test patch:
diff --git a/view/jpa/src/test/kotlin/io/holunda/polyflow/view/jpa/JpaPolyflowViewServiceTaskITest.kt b/view/jpa/src/test/kotlin/io/holunda/polyflow/view/jpa/JpaPolyflowViewServiceTaskITest.kt
index dc9d2e3c3..1c483ad53 100644
--- a/view/jpa/src/test/kotlin/io/holunda/polyflow/view/jpa/JpaPolyflowViewServiceTaskITest.kt
+++ b/view/jpa/src/test/kotlin/io/holunda/polyflow/view/jpa/JpaPolyflowViewServiceTaskITest.kt
@@ -275,6 +275,23 @@ internal class JpaPolyflowViewServiceTaskITest {
     assertThat(strawhats.elements[1].dataEntries[0].entryId).isEqualTo(dataId1)
   }
 
+  @Test
+  fun `should find the task by user with data entries and sort results correctly`() {
+    val strawhats = jpaPolyflowViewService.query(TasksWithDataEntriesForUserQuery(
+      user = User("other", setOf("strawhats")),
+      sort = "+name"
+    ))
+    val strawhatsInverse = jpaPolyflowViewService.query(TasksWithDataEntriesForUserQuery(
+      user = User("other", setOf("strawhats")),
+      sort = "-name"
+    ))
+
+    assertThat(strawhats.elements).isNotEmpty.hasSize(2)
+    assertThat(strawhats.elements.map { it.task.id }).containsExactly(id3, id4)
+    assertThat(strawhatsInverse.elements).isNotEmpty.hasSize(2)
+    assertThat(strawhatsInverse.elements.map { it.task.id }).containsExactly(id4, id3)
+  }
+
   @Test
   fun `should find the task by group with data entries`() {
     val strawhats = jpaPolyflowViewService.query(TasksWithDataEntriesForGroupQuery(user = User("some", setOf("strawhats")), includeAssigned = false))
diff --git a/view/jpa/src/test/kotlin/io/holunda/polyflow/view/jpa/SpecificationTest.kt b/view/jpa/src/test/kotlin/io/holunda/polyflow/view/jpa/SpecificationTest.kt
index 5c33a2ec1..fb7f95bb2 100644
--- a/view/jpa/src/test/kotlin/io/holunda/polyflow/view/jpa/SpecificationTest.kt
+++ b/view/jpa/src/test/kotlin/io/holunda/polyflow/view/jpa/SpecificationTest.kt
@@ -6,6 +6,7 @@ import io.holunda.polyflow.view.jpa.auth.AuthorizationPrincipal.Companion.user
 import io.holunda.polyflow.view.jpa.data.DataEntryRepository
 import org.assertj.core.api.Assertions.assertThat
 import org.junit.jupiter.api.Test
+import org.springframework.data.domain.Sort.Direction
 
 /**
  * Tests conversion of criteria into JPA Specifications.
@@ -51,11 +52,19 @@ internal class SpecificationTest {
 
   @Test
   fun `creates a paged request`() {
-    val request = pageRequest(page = 15, size = 42, "+name")
-    assertThat(request.pageNumber).isEqualTo(15)
-    assertThat(request.pageSize).isEqualTo(42)
-    assertThat(request.sort.isSorted).isEqualTo(true)
-    assertThat(request.sort.isEmpty).isEqualTo(false)
+    val requestAsc = pageRequest(page = 15, size = 42, "+name")
+    assertThat(requestAsc.pageNumber).isEqualTo(15)
+    assertThat(requestAsc.pageSize).isEqualTo(42)
+    assertThat(requestAsc.sort.isSorted).isEqualTo(true)
+    assertThat(requestAsc.sort.isEmpty).isEqualTo(false)
+    assertThat(requestAsc.sort.getOrderFor("name")!!.direction).isEqualTo(Direction.ASC)
+
+    val requestDesc = pageRequest(page = 15, size = 42, "-name")
+    assertThat(requestDesc.pageNumber).isEqualTo(15)
+    assertThat(requestDesc.pageSize).isEqualTo(42)
+    assertThat(requestDesc.sort.isSorted).isEqualTo(true)
+    assertThat(requestDesc.sort.isEmpty).isEqualTo(false)
+    assertThat(requestDesc.sort.getOrderFor("name")!!.direction).isEqualTo(Direction.DESC)
 
     val unsorted = pageRequest(page = 14, size = 41, null)
     assertThat(unsorted.pageNumber).isEqualTo(14)