package com.vtence.molecule.middlewares;

import com.vtence.molecule.Request;
import com.vtence.molecule.Response;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import java.util.Locale;

import static com.vtence.molecule.testing.RequestAssert.assertThat;

public class LocalesTest {

    Locale DEFAULT_LOCALE = Locale.US;
    Locale originalDefault = Locale.getDefault();

    Request request = new Request();
    Response response = new Response();

    @Before
    public void setPlatformDefaultLocale() {
        Locale.setDefault(DEFAULT_LOCALE);
    }

    @After
    public void restoreDefaultPlatformLocale() {
        Locale.setDefault(originalDefault);
    }

    @Test
    public void usesThePlatformLocaleAsTheDefault() throws Exception {
        Locales locales = new Locales();
        locales.handle(request, response);

        assertThat(request).hasAttribute(Locale.class, DEFAULT_LOCALE);
    }

    @Test
    public void usesTheRequestedLanguageIfSupported() throws Exception {
        Locales locales = new Locales("en", "fr");
        locales.handle(request.header("Accept-Language", "fr"), response);

        assertThat(request).hasAttribute(Locale.class, Locale.FRENCH);
    }

    @Test
    public void usesTheHighestQualityLanguageSupported() throws Exception {
        Locales locales = new Locales("en", "fr");
        locales.handle(request.header("Accept-Language", "en; q=0.8, fr"), response);

        assertThat(request).hasAttribute(Locale.class, Locale.FRENCH);
    }

    @Test
    public void fallsBackToPlatformDefaultForUnsupportedLanguages() throws Exception {
        Locales locales = new Locales("en", "fr");
        locales.handle(request.header("Accept-Language", "es-ES"), response);

        assertThat(request).hasAttribute(Locale.class, DEFAULT_LOCALE);
    }

    @Test
    public void ignoresMalformedLanguageTags() throws Exception {
        Locales locales = new Locales("en", "fr");
        locales.handle(request.header("Accept-Language", "-fr-"), response);

        assertThat(request).hasAttribute(Locale.class, DEFAULT_LOCALE);
    }

    @Test public void
    unbindsPreferredLocaleDone() throws Exception {
        Locales locales = new Locales();
        locales.handle(request, response);

        assertThat(request).hasNoAttribute(Locale.class);
    }
}
@@ -35,16 +35,56 @@
 wares;%0A%0A
+import com.vtence.molecule.Application;%0A
 import c
@@ -314,16 +314,153 @@
 ertThat;
+%0Aimport static java.util.Locale.FRENCH;%0Aimport static org.hamcrest.MatcherAssert.assertThat;%0Aimport static org.hamcrest.Matchers.equalTo;
 %0A%0Apublic
@@ -569,16 +569,37 @@
 fault();
+%0A    Locale selected;
 %0A%0A    Re
@@ -981,140 +981,67 @@
     
-Locales locales = new Locales();%0A        locales.handle(request, response);%0A%0A        assertThat(request).hasAttribute(Locale.class, 
+assertThat(selectPreferred(null, fromSupported()), equalTo(
 DEFA
@@ -1043,32 +1043,33 @@
 (DEFAULT_LOCALE)
+)
 ;%0A    %7D%0A%0A    @Te
@@ -1156,113 +1156,66 @@
     
-Locales locales = new Locales(%22en
+assertThat(selectPreferred(%22fr
 %22, 
-%22
 fr
-%22);%0A        locales.handle(request.header(%22Accept-Language
+omSupported(%22en
 %22, %22fr%22)
 , re
@@ -1214,91 +1214,27 @@
 fr%22)
+)
 , 
-response);%0A%0A        assertThat(request).hasAttribute(Locale.class, Locale.
+equalTo(
 FRENCH)
+)
 ;%0A  
@@ -1336,108 +1336,35 @@
     
-Locales locales = new Locales(%22en%22, %22fr%22);%0A        locales.handle(request.header(%22Accept-Language%22, 
+assertThat(selectPreferred(
 %22en;
@@ -1378,92 +1378,54 @@
  fr%22
-)
 , 
-response);%0A%0A        assertThat(request).hasAttribute(Locale.class, Locale.
+fromSupported(%22en%22, %22fr%22)), equalTo(
 FRENCH)
+)
 ;%0A  
@@ -1538,185 +1538,260 @@
     
-Locales locales = new Locales(%22en%22, %22fr%22
+assertThat(selectPreferred(%22es-ES%22, fromSupported(%22en%22, %22fr%22)), equalTo(DEFAULT_LOCALE)
 );%0A    
+%7D%0A%0A
     
-locales.handle(request.header(%22Accept-Language%22, %22es-ES%22), response);%0A%0A        assertThat(request).hasAttribute(Locale.class, 
+@Test%0A    public void ignoresMalformedLanguageTags() throws Exception %7B%0A        assertThat(selectPreferred(%22-fr-%22, fromSupported(%22en%22, %22fr%22)), equalTo(
 DEFA
@@ -1793,32 +1793,33 @@
 (DEFAULT_LOCALE)
+)
 ;%0A    %7D%0A%0A    @Te
@@ -1812,36 +1812,32 @@
     %7D%0A%0A    @Test
-%0A   
  public void ign
@@ -1836,37 +1836,39 @@
 void
- ignoresMalformedLanguageTags
+%0A    unbindsPreferredLocaleDone
 () t
@@ -1923,26 +1923,16 @@
 Locales(
-%22en%22, %22fr%22
 );%0A     
@@ -1960,42 +1960,8 @@
 uest
-.header(%22Accept-Language%22, %22-fr-%22)
 , re
@@ -2001,16 +2001,18 @@
 est).has
+No
 Attribut
@@ -2029,87 +2029,89 @@
 lass
-, DEFAULT_LOCALE);%0A    %7D%0A%0A    @Test public void%0A    unbindsPreferredLocaleDone(
+);%0A    %7D%0A%0A    private Locale selectPreferred(String accepted, String... supported
 ) th
@@ -2157,32 +2157,41 @@
 s = new Locales(
+supported
 );%0A        local
@@ -2197,92 +2197,426 @@
 les.
-handle(request, response);%0A%0A        assertThat(request).hasNoAttribute(Locale.class)
+connectTo(new Application() %7B%0A            @Override%0A            public void handle(Request request, Response response) throws Exception %7B%0A                selected = request.attribute(Locale.class);%0A            %7D%0A        %7D);%0A        locales.handle(request.header(%22Accept-Language%22, accepted), response);%0A%0A        return selected;%0A    %7D%0A%0A    private String%5B%5D fromSupported(String... supported) %7B%0A        return supported
 ;%0A  

Check locale negotiation result down the middleware stack now that we unbind locale from request after processing