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.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; import java.util.Locale; import java.util.concurrent.ExecutionException; import static com.vtence.molecule.testing.RequestAssert.assertThat; import static java.util.Locale.FRENCH; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.notNullValue; public class LocalesTest { Locale DEFAULT_LOCALE = Locale.US; Locale originalDefault = Locale.getDefault(); Locale selected; Request request = new Request(); Response response = new Response(); @Rule public ExpectedException error = ExpectedException.none(); @Before public void setPlatformDefaultLocale() { Locale.setDefault(DEFAULT_LOCALE); } @After public void restoreDefaultPlatformLocale() { Locale.setDefault(originalDefault); } @Test public void usesThePlatformLocaleAsTheDefault() throws Exception { assertThat(selectPreferred(null, fromSupported()), equalTo(DEFAULT_LOCALE)); } @Test public void usesTheRequestedLanguageIfSupported() throws Exception { assertThat(selectPreferred("fr", fromSupported("en", "fr")), equalTo(FRENCH)); } @Test public void usesTheHighestQualityLanguageSupported() throws Exception { assertThat(selectPreferred("en; q=0.8, fr", fromSupported("en", "fr")), equalTo(FRENCH)); } @Test public void fallsBackToPlatformDefaultForUnsupportedLanguages() throws Exception { assertThat(selectPreferred("es-ES", fromSupported("en", "fr")), equalTo(DEFAULT_LOCALE)); } @Test public void ignoresMalformedLanguageTags() throws Exception { assertThat(selectPreferred("-fr-", fromSupported("en", "fr")), equalTo(DEFAULT_LOCALE)); } @Test public void unbindsPreferredLocaleOnceDone() throws Exception { Locales locales = new Locales(); locales.handle(request, response); assertThat(request).hasAttribute(Locale.class, notNullValue()); response.done(); assertNoExecutionError(); assertThat(request).hasNoAttribute(Locale.class); } private void assertNoExecutionError() throws ExecutionException, InterruptedException { response.await(); } @Test public void unbindsPreferredLocaleInCaseOfDeferredErrors() throws Exception { Locales locales = new Locales(); locales.handle(request, response); response.done(new Exception("Error!")); assertThat(request).hasNoAttribute(Locale.class); } @Test public void unbindsPreferredLocaleWhenAnErrorOccurs() throws Exception { Locales locales = new Locales(); locales.connectTo((request, response) -> { throw new Exception("Error!"); }); error.expectMessage("Error!"); try { locales.handle(request, response); } finally { assertThat(request).hasNoAttribute(Locale.class); } } private Locale selectPreferred(String accepted, String... supported) throws Exception { Locales locales = new Locales(supported); locales.connectTo((request, response) -> selected = request.attribute(Locale.class)); locales.handle(request.header("Accept-Language", accepted), response); return selected; } private String[] fromSupported(String... supported) { return supported; } }