package org.synyx.urlaubsverwaltung.search;

import org.junit.jupiter.api.Test;
import org.springframework.data.domain.Sort;

import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

import static java.util.stream.Collectors.toList;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertThrows;

class SortComparatorTest {

    @Test
    void ensureSortingAsc() {
        final Sort sort = Sort.by(Sort.Direction.ASC, "integer").and(Sort.by(Sort.Direction.ASC, "string"));
        final SortComparator<SomeClassToSort> sut = new SortComparator<>(SomeClassToSort.class, sort);

        final List<SomeClassToSort> list = List.of(
            new SomeClassToSort(2, "aaa"),
            new SomeClassToSort(1, "aaa"),
            new SomeClassToSort(3, "bbb"),
            new SomeClassToSort(3, "aaa")
        );

        final List<SomeClassToSort> sorted = list.stream().sorted(sut).collect(toList());

        assertThat(sorted).containsExactly(
            new SomeClassToSort(1, "aaa"),
            new SomeClassToSort(2, "aaa"),
            new SomeClassToSort(3, "aaa"),
            new SomeClassToSort(3, "bbb")
        );
    }

    @Test
    void ensureSortingDesc() {
        final Sort sort = Sort.by(Sort.Direction.ASC, "integer").and(Sort.by(Sort.Direction.DESC, "string"));
        final SortComparator<SomeClassToSort> sut = new SortComparator<>(SomeClassToSort.class, sort);

        final List<SomeClassToSort> list = List.of(
            new SomeClassToSort(2, "aaa"),
            new SomeClassToSort(1, "aaa"),
            new SomeClassToSort(3, "bbb"),
            new SomeClassToSort(3, "aaa")
        );

        final List<SomeClassToSort> sorted = list.stream().sorted(sut).collect(toList());

        assertThat(sorted).containsExactly(
            new SomeClassToSort(1, "aaa"),
            new SomeClassToSort(2, "aaa"),
            new SomeClassToSort(3, "bbb"),
            new SomeClassToSort(3, "aaa")
        );
    }

    @Test
    void ensureEmptyComparatorForUnsorted() {
        final SortComparator<SomeClassToSort> sut = new SortComparator<>(SomeClassToSort.class, Sort.unsorted());

        final List<SomeClassToSort> list = List.of(
            new SomeClassToSort(2, "aaa"),
            new SomeClassToSort(1, "bbb")
        );

        final List<SomeClassToSort> sorted = list.stream().sorted(sut).collect(toList());

        assertThat(sorted).containsExactly(
            new SomeClassToSort(2, "aaa"),
            new SomeClassToSort(1, "bbb")
        );
    }

    @Test
    void ensureRobustHandlingForUnknownSortProperty() {
        final Sort sortAscByInteger = Sort.by("unknownAttribute");
        final SortComparator<SomeClassToSort> sut = new SortComparator<>(SomeClassToSort.class, sortAscByInteger);
        final List<SomeClassToSort> list = List.of(new SomeClassToSort(2, "aaa"), new SomeClassToSort(1, "bbb"));

        final List<SomeClassToSort> sorted = list.stream().sorted(sut).collect(toList());
        assertThat(sorted).containsExactly(
            new SomeClassToSort(2, "aaa"),
            new SomeClassToSort(1, "bbb")
        );
    }

    static class SomeClassToSort {
        private final int integer;
        private final String string;

        SomeClassToSort(int integer, String string) {
            this.integer = integer;
            this.string = string;
        }

        public int getInteger() {
            return integer;
        }

        public String getString() {
            return string;
        }

        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;
            SomeClassToSort that = (SomeClassToSort) o;
            return integer == that.integer && Objects.equals(string, that.string);
        }

        @Override
        public int hashCode() {
            return Objects.hash(integer, string);
        }
    }
}

@@ -171,44 +171,8 @@
 cts;
-%0Aimport java.util.stream.Collectors;
 %0A%0Aim
@@ -280,69 +280,8 @@
 hat;
-%0Aimport static org.junit.jupiter.api.Assertions.assertThrows;
 %0A%0Acl
@@ -3086,24 +3086,599 @@
   );%0A    %7D%0A%0A
+    @Test%0A    void ensureNullValuesAreBasedAtTheEnd() %7B%0A        final Sort sort = Sort.by(Sort.Direction.DESC, %22string%22);%0A        final SortComparator%3CSomeClassToSort%3E sut = new SortComparator%3C%3E(SomeClassToSort.class, sort);%0A        final List%3CSomeClassToSort%3E list = List.of(new SomeClassToSort(2, null), new SomeClassToSort(1, %22bbb%22));%0A%0A        final List%3CSomeClassToSort%3E sorted = list.stream().sorted(sut).collect(toList());%0A        assertThat(sorted).containsExactly(%0A            new SomeClassToSort(1, %22bbb%22),%0A            new SomeClassToSort(2, null)%0A        );%0A    %7D%0A%0A
     static c

Add SortComparator test to ensure null values at the end