Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

[#1412] Modified 'Implemented resolving nearest matching locale.' to …

…not break API + added tests

Also had to fix an existing test because it was unpredictable - It tests the same thing after the modification but in a predictable way
  • Loading branch information...
commit 96f194093c5e21b7c8bce52cd448a79474620236 1 parent a1f7abf
Morten Kjetland mbknor authored
1  .gitignore
View
@@ -124,6 +124,7 @@ samples-and-tests/zencontact/logs
samples-and-tests/zencontact/test-result
samples-and-tests/zencontact/tmp
modules/scala
+atlassian-ide-plugin.xml
modules/*
build.classes
modules/crud/nbproject
38 framework/src/play/i18n/Lang.java
View
@@ -69,16 +69,27 @@ public static void clear() {
*/
public static void change(String locale) {
String closestLocale = findClosestMatch(Collections.singleton(locale));
- boolean success = set(closestLocale);
- //findClosestMatch should always return a valid locale, so success should always be true.
- Response.current().setCookie(Play.configuration.getProperty("application.lang.cookie", "PLAY_LANG"), locale);
+ if ( closestLocale == null ) {
+ // Give up
+ return ;
+ }
+ if ( set(closestLocale) ) {
+ Response response = Response.current();
+ if ( response != null ) {
+ // We have a current response in scope - set the language-cookie to store the selected language for the next requests
+ response.setCookie(Play.configuration.getProperty("application.lang.cookie", "PLAY_LANG"), locale);
+ }
+ }
+
}
/**
* Given a set of desired locales, searches the set of locales supported by this Play! application and returns the closest match.
*
- * @param desiredLocales a collection of desired locales. If the collection is ordered, earlier locales are preferred over later ones. Locales should be of the form "[language]_[country" or "[language]", e.g. "en_CA" or "en". The locale strings are case insensitive (e.g. "EN_CA" is considered the same as "en_ca").
- * @return the closest matching locale. If no locales are defined in this Play! application, the empty string is returned.
+ * @param desiredLocales a collection of desired locales. If the collection is ordered, earlier locales are preferred over later ones.
+ * Locales should be of the form "[language]_[country" or "[language]", e.g. "en_CA" or "en".
+ * The locale strings are case insensitive (e.g. "EN_CA" is considered the same as "en_ca").
+ * @return the closest matching locale. If no closest match for a language/country is found, null is returned
*/
private static String findClosestMatch(Iterable<String> desiredLocales) {
//look for an exact match
@@ -106,12 +117,9 @@ private static String findClosestMatch(Iterable<String> desiredLocales) {
}
}
}
- //No matches found. Return default locale
- if (Play.langs.isEmpty()) {
- return "";
- } else {
- return Play.langs.get(0);
- }
+
+ // We did not find a anything
+ return null;
}
/**
@@ -140,7 +148,13 @@ private static void resolvefrom(Request request) {
}
String closestLocaleMatch = findClosestMatch(request.acceptLanguage());
- set(closestLocaleMatch);
+ if ( closestLocaleMatch != null ) {
+ set(closestLocaleMatch);
+ } else {
+ // Did not find anything - use default
+ setDefaultLocale();
+ }
+
}
public static void setDefaultLocale() {
142 framework/test-src/play/i18n/LangTest.java
View
@@ -0,0 +1,142 @@
+package play.i18n;
+
+import org.junit.Test;
+import play.Play;
+import play.PlayBuilder;
+import play.mvc.Http;
+import play.test.FunctionalTest;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+
+import static org.fest.assertions.Assertions.*;
+
+public class LangTest {
+
+ @Test
+ public void testChange() {
+ new PlayBuilder().build();
+ Play.langs = Arrays.asList("no", "en", "fr");
+ Lang.current.set(null);
+ assertThat(Lang.current.get()).isNull();
+
+ Lang.change("no");
+ assertThat(Lang.current.get()).isEqualTo("no");
+ Lang.change("nox");
+ assertThat(Lang.current.get()).isEqualTo("no");
+ Lang.change("EN");
+ assertThat(Lang.current.get()).isEqualTo("en");
+ Lang.change("fr");
+ assertThat(Lang.current.get()).isEqualTo("fr");
+
+ Lang.change("xx");
+ assertThat(Lang.current.get()).isEqualTo("fr");
+
+ Lang.change("en_uk");
+ assertThat(Lang.current.get()).isEqualTo("en");
+
+ Play.langs = Arrays.asList("no", "en", "en_uk", "fr");
+ Lang.current.set(null);
+ Lang.change("en_uk");
+ assertThat(Lang.current.get()).isEqualTo("en_uk");
+ Lang.change("en");
+ assertThat(Lang.current.get()).isEqualTo("en");
+ Lang.change("en_qw");
+ assertThat(Lang.current.get()).isEqualTo("en");
+ }
+
+ @Test
+ public void testGet() {
+ new PlayBuilder().build();
+ Play.langs = Arrays.asList("no", "en", "en_uk", "fr");
+ Lang.current.set(null);
+
+ Http.Response.current.set( new Http.Response());
+
+ // check default when missing request
+ Http.Request.current.set(null);
+ assertThat(Lang.get()).isEqualTo("no");
+
+ // check default when missing info in request
+ Http.Request req = FunctionalTest.newRequest();
+ Http.Request.current.set(req);
+ Lang.current.set(null);
+ assertThat(Lang.get()).isEqualTo("no");
+
+ // check only with accept-language, without cookie value
+ req = FunctionalTest.newRequest();
+ req.headers.put("accept-language", new Http.Header("accept-language", "x"));
+ Http.Request.current.set(req);
+ Lang.current.set(null);
+ assertThat(Lang.get()).isEqualTo("no");
+
+ req = FunctionalTest.newRequest();
+ req.headers.put("accept-language", new Http.Header("accept-language", "no"));
+ Http.Request.current.set(req);
+ Lang.current.set(null);
+ assertThat(Lang.get()).isEqualTo("no");
+
+ req = FunctionalTest.newRequest();
+ req.headers.put("accept-language", new Http.Header("accept-language", "en"));
+ Http.Request.current.set(req);
+ Lang.current.set(null);
+ assertThat(Lang.get()).isEqualTo("en");
+
+ req = FunctionalTest.newRequest();
+ req.headers.put("accept-language", new Http.Header("accept-language", "x,en"));
+ Http.Request.current.set(req);
+ Lang.current.set(null);
+ assertThat(Lang.get()).isEqualTo("en");
+
+ req = FunctionalTest.newRequest();
+ req.headers.put("accept-language", new Http.Header("accept-language", "en_uk"));
+ Http.Request.current.set(req);
+ Lang.current.set(null);
+ assertThat(Lang.get()).isEqualTo("en_uk");
+
+ req = FunctionalTest.newRequest();
+ req.headers.put("accept-language", new Http.Header("accept-language", "x,en_uk"));
+ Http.Request.current.set(req);
+ Lang.current.set(null);
+ assertThat(Lang.get()).isEqualTo("en_uk");
+
+ // check with cookie value
+
+ req = FunctionalTest.newRequest();
+
+ Http.Cookie cookie = new Http.Cookie();
+ cookie.name = "PLAY_LANG";
+ cookie.value = "x";//not found in cookie
+ req.cookies.put(cookie.name, cookie);
+ req.headers.put("accept-language", new Http.Header("accept-language", "en"));
+ Http.Request.current.set(req);
+ Lang.current.set(null);
+ assertThat(Lang.get()).isEqualTo("en");
+
+ cookie = new Http.Cookie();
+ cookie.name = "PLAY_LANG";
+ cookie.value = "en";
+ req.cookies.put(cookie.name, cookie);
+ Http.Request.current.set(req);
+ Lang.current.set(null);
+ assertThat(Lang.get()).isEqualTo("en");
+
+ cookie = new Http.Cookie();
+ cookie.name = "PLAY_LANG";
+ cookie.value = "en_q";
+ req.cookies.put(cookie.name, cookie);
+ Http.Request.current.set(req);
+ Lang.current.set(null);
+ assertThat(Lang.get()).isEqualTo("en");
+
+ cookie = new Http.Cookie();
+ cookie.name = "PLAY_LANG";
+ cookie.value = "en_uk";
+ req.cookies.put(cookie.name, cookie);
+ Http.Request.current.set(req);
+ Lang.current.set(null);
+ assertThat(Lang.get()).isEqualTo("en_uk");
+
+
+ }
+}
5 samples-and-tests/just-test-cases/app/controllers/Application.java
View
@@ -129,6 +129,11 @@ public static void tagContexts() {
render();
}
+
+ public static void generateBookWithDateLink(long timeLong) {
+ render(timeLong);
+ }
+
public static void book(Date at) {
java.text.SimpleDateFormat df = new java.text.SimpleDateFormat("dd/MM/yy");
df.setTimeZone(TimeZone.getTimeZone("UTC"));
5 samples-and-tests/just-test-cases/app/views/Application/generateBookWithDateLink.html
View
@@ -0,0 +1,5 @@
+<html>
+<body>
+ <a id="timeLink" href="@{Application.book(new java.util.Date(timeLong))}">link</a>
+</body>
+</html>
10 samples-and-tests/just-test-cases/test/binding.test.html
View
@@ -75,8 +75,14 @@
<!-- Now unbind dates -->
open('/databinding/changeLanguage/en/')
- open('@{Application.book(new java.util.Date(2879877856556))}')
- assertTextPresent('Booked at 04/04/61 !!')
+ <!-- Since it is unclear which locale is current when rendering this selenium page,
+ we cannot rely on the auto-date-unbinding when generating the url with patams here.
+ To test the same stuff´, we therefor request a page from the server (which has the correct lang, en)
+ which generates the link we need, then we click it.
+ We end up testing the exact same stuff, only under known locale conditions. -->
+ open('@{Application.generateBookWithDateLink(2879877856556)}')
+ clickAndWait('timeLink')
+ assertTextPresent('Booked at 04/04/61 !!')
<!-- Binding internal enum with empty string -->
open('/databinding/createFactory?factory.name=Nestle&factory.color=RED')
Please sign in to comment.
Something went wrong with that request. Please try again.