package common.controllers;

import io.sphere.sdk.categories.Category;
import org.junit.Test;

import java.util.List;
import java.util.Locale;
import java.util.function.Consumer;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import static io.sphere.sdk.json.SphereJsonUtils.readObject;
import static java.util.Arrays.asList;
import static java.util.Locale.ENGLISH;
import static org.assertj.core.api.Assertions.assertThat;

public class ByNameCategoryComparatorTest {

    @Test
    public void sortsAccordingToTheProvidedLocale() {
        List<Category> categories = asList(category(PANTS), category(SHIRTS), category(DRESSES));
        sort(categories, ENGLISH, (sortedNames) -> assertThat(sortedNames).containsExactly("Dresses", "Pants", "Shirts"));
    }

    @Test
    public void sortsWhenTheLocalizedNameForTheProvidedLocaleIsMissing() {
        List<Category> categories = asList(category(PANTS), category(SHIRTS_WITHOUT_ENGLISH), category(DRESSES));
        sort(categories, ENGLISH, (sortedNames) -> assertThat(sortedNames).containsExactly(null, "Dresses", "Pants"));
    }

    private void sort(List<Category> unsortedList, Locale locale, Consumer<List<String>> test) {
        final Stream<Category> sortedCategories = unsortedList.stream().sorted(new ByNameCategoryComparator(locale));
        final Stream<String> sortedNames = sortedCategories.map(category -> category.getName().get(locale));
        test.accept(sortedNames.collect(Collectors.toList()));
    }

    private static Category category(final String jsonAsString) {
        return readObject(jsonAsString, Category.typeReference());
    }

    private static final String PANTS =
            "{" +
            "  \"name\": {" +
            "    \"en\": \"Pants\"," +
            "    \"de\" : \"Hose\"" +
            "  }" +
            "}";

    private static final String SHIRTS =
            "{" +
            "  \"name\": {" +
            "    \"en\": \"Shirts\"," +
            "    \"de\" : \"Hemden\"" +
            "  }" +
            "}";

    private static final String DRESSES =
            "{" +
            "  \"name\": {" +
            "    \"en\": \"Dresses\"," +
            "    \"de\" : \"Kleider\"" +
            "  }" +
            "}";

    private static final String SHIRTS_WITHOUT_ENGLISH =
            "{" +
            "  \"name\": {" +
            "    \"de\" : \"Hemden\"" +
            "  }" +
            "}";
}

@@ -88,16 +88,50 @@
 .Test;%0A%0A
+import javax.annotation.Nullable;%0A
 import j
@@ -166,24 +166,51 @@
 til.Locale;%0A
+import java.util.Optional;%0A
 import java.
@@ -666,50 +666,85 @@
 ory(
-PANTS), category(SHIRTS), category(DRESSES
+%22Pants%22, %22Hose%22), category(%22Shirts%22, %22Hemden%22), category(%22Dresses%22, %22Kleider%22
 ));%0A
@@ -1014,66 +1014,81 @@
 ory(
-PANTS), category(SHIRTS_WITHOUT_ENGLISH), category(DRESSES
+%22Pants%22, %22Hose%22), category(null, %22Hemden%22), category(%22Dresses%22, %22Kleider%22
 ));%0A
@@ -1644,16 +1644,26 @@
 ategory(
+@Nullable 
 final St
@@ -1671,319 +1671,172 @@
 ing 
-jsonAsString) %7B%0A        return readObject(jsonAsString, Category.typeReference());
+englishName, final String germanName) %7B
 %0A    
-%7D%0A%0A
     
-private static final String PANTS =%0A            %22%7B%22 +%0A            %22  %5C%22name%5C%22: %7B%22 +%0A            %22    %5C%22en%5C%22: %5C%22Pants%5C%22,%22 +%0A            %22    %5C%22de%5C%22 : %5C%22Hose%5C%22%22 +%0A            %22  %7D%22 +%0A            %22%7D%22;%0A%0A    private static
+final String englishNameJson = Optional.ofNullable(englishName).map(e -%3E %22%5C%22en%5C%22: %5C%22%22+ e +%22%5C%22,%22).orElse(%22%22);%0A       
  fin
@@ -1845,22 +1845,20 @@
  String 
-SHIRTS
+json
  =%0A     
@@ -1868,39 +1868,13 @@
     
-%22%7B%22 +%0A            %22  %5C%22name%5C%22: 
+    %22
 %7B%22 +
@@ -1890,72 +1890,26 @@
     
-%22
     
-%5C%22en%5C%22: %5C%22Shirts%5C%22,%22 +%0A            %22  
+%22
   %5C%22
-d
+nam
 e%5C%22
- 
 : 
-%5C%22Hemden%5C%22
+%7B
 %22 +%0A
@@ -1924,75 +1924,33 @@
     
-%22  %7D%22 +%0A            %22%7D%22;%0A%0A    private static final String DRESSES =
+        englishNameJson +
 %0A   
@@ -1962,81 +1962,47 @@
     
-%22%7B%22 +%0A
     
+%22
     
-    %22  %5C%22nam
+%5C%22d
 e%5C%22
+ 
 : 
-%7B%22 +%0A            %22    %5C%22en%5C%22: %5C%22Dresses
+%5C%22%22+ germanName + %22
 %5C%22
-,
 %22 +%0A
@@ -2017,57 +2017,20 @@
     
-%22
     
-%5C%22de%5C%22 : %5C%22Kleider%5C%22%22 +%0A            
 %22  %7D%22 +%0A
     
@@ -2017,32 +2017,36 @@
         %22  %7D%22 +%0A
+    
             %22%7D%22;
@@ -2050,189 +2050,71 @@
 %7D%22;%0A
-%0A
     
-private static final String SHIRTS_WITHOUT_ENGLISH =%0A            %22%7B%22 +%0A            %22  %5C%22name%5C%22: %7B%22 +%0A            %22    %5C%22de%5C%22 : %5C%22Hemden%5C%22%22 +%0A            %22  %7D%22 +%0A            %22%7D%22;
+    return readObject(json, Category.typeReference());%0A    %7D
 %0A%7D%0A

Improve generation of JSON for tests