keycloak-aplcache

KEYCLOAK-7196: Add kc_locale to keycloak.js (#5165) * KEYCLOAK-7196:

4/23/2018 12:45:32 PM

Details

diff --git a/adapters/oidc/js/src/main/resources/keycloak.d.ts b/adapters/oidc/js/src/main/resources/keycloak.d.ts
index fe1ac48..2a1c46d 100644
--- a/adapters/oidc/js/src/main/resources/keycloak.d.ts
+++ b/adapters/oidc/js/src/main/resources/keycloak.d.ts
@@ -149,10 +149,18 @@ declare namespace Keycloak {
 		 */
 		idpHint?: string;
 
-		/**
-		 * Specifies the desired locale for the UI.
+	        /**
+		 * Sets the 'ui_locales' query param in compliance with section 3.1.2.1
+                 * of the OIDC 1.0 specification.
 		 */
 		locale?: string;
+                
+                /**
+		 * Specifies the desired Keycloak locale for the UI.  This differs from
+                 * the locale param in that it tells the Keycloak server to set a cookie and update
+                 * the user's profile to a new preferred locale.
+		 */
+		kcLocale?: string;
 	}
 
 	type KeycloakPromiseCallback<T> = (result: T) => void;
diff --git a/adapters/oidc/js/src/main/resources/keycloak.js b/adapters/oidc/js/src/main/resources/keycloak.js
index c4ddcc1..271cd50 100755
--- a/adapters/oidc/js/src/main/resources/keycloak.js
+++ b/adapters/oidc/js/src/main/resources/keycloak.js
@@ -282,6 +282,10 @@
             if (options && options.locale) {
                 url += '&ui_locales=' + encodeURIComponent(options.locale);
             }
+            
+            if (options && options.kcLocale) {
+                url += '&kc_locale=' + encodeURIComponent(options.kcLocale);
+            }
 
             return url;
         }
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/javascript/AbstractJavascriptTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/javascript/AbstractJavascriptTest.java
index e42e4b0..2ec7bea 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/javascript/AbstractJavascriptTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/javascript/AbstractJavascriptTest.java
@@ -26,6 +26,9 @@ import static org.hamcrest.CoreMatchers.containsString;
 import static org.hamcrest.collection.IsMapContaining.hasEntry;
 import static org.keycloak.testsuite.util.URLAssert.assertCurrentUrlStartsWith;
 import static org.keycloak.testsuite.util.WaitUtils.waitUntilElement;
+import static org.keycloak.testsuite.util.WaitUtils.waitForPageToLoad;
+import org.openqa.selenium.Cookie;
+import org.openqa.selenium.WebDriver.Options;
 
 /**
  * @author mhajas
@@ -142,6 +145,18 @@ public abstract class AbstractJavascriptTest extends AbstractAuthTest {
     public void assertOutputWebElementContains(String value, WebDriver driver1, Object output, WebElement events) {
         waitUntilElement((WebElement) output).text().contains(value);
     }
+    
+    public void assertLocaleCookie(String locale, WebDriver driver1, Object output, WebElement events) {
+        waitForPageToLoad();
+        Options ops = driver1.manage();
+        Cookie cookie = ops.getCookieNamed("KEYCLOAK_LOCALE");
+        Assert.assertNotNull(cookie);
+        Assert.assertEquals(locale, cookie.getValue());
+    }
+    
+    public JavascriptStateValidator assertLocaleIsSet(String locale) {
+        return buildFunction(this::assertLocaleCookie, locale);
+    }
 
     public void assertOutputContains(String value, WebDriver driver1, Object output, WebElement events) {
         if (output instanceof WebElement) {
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/javascript/JavascriptAdapterTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/javascript/JavascriptAdapterTest.java
index 1232e45..e434394 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/javascript/JavascriptAdapterTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/javascript/JavascriptAdapterTest.java
@@ -33,6 +33,8 @@ import java.util.List;
 import java.util.Map;
 
 import static java.lang.Math.toIntExact;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
 import static org.hamcrest.CoreMatchers.both;
 import static org.hamcrest.CoreMatchers.containsString;
 import static org.hamcrest.Matchers.greaterThan;
@@ -42,6 +44,7 @@ import static org.hamcrest.collection.IsMapContaining.hasEntry;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertThat;
 import static org.junit.Assert.assertTrue;
+import org.keycloak.testsuite.ProfileAssume;
 import static org.keycloak.testsuite.util.URLAssert.assertCurrentUrlDoesntStartWith;
 import static org.keycloak.testsuite.util.URLAssert.assertCurrentUrlStartsWith;
 import static org.keycloak.testsuite.util.WaitUtils.waitUntilElement;
@@ -114,6 +117,25 @@ public class JavascriptAdapterTest extends AbstractJavascriptTest {
     }
 
     @Test
+    public void testLoginWithKCLocale() {
+        ProfileAssume.assumeCommunity();
+
+        RealmRepresentation testRealmRep = testRealmResource().toRepresentation();
+        testRealmRep.setInternationalizationEnabled(true);
+        testRealmRep.setDefaultLocale("en");
+        testRealmRep.setSupportedLocales(Stream.of("en", "de").collect(Collectors.toSet()));
+        testRealmResource().update(testRealmRep);
+        
+        testExecutor.init(defaultArguments(), this::assertInitNotAuth)
+                .login(this::assertOnLoginPage)
+                .loginForm(testUser, this::assertOnTestAppUrl)
+                .init(defaultArguments(), this::assertSuccessfullyLoggedIn)
+                .login("{kcLocale: 'de'}", assertLocaleIsSet("de"))
+                .init(defaultArguments(), this::assertSuccessfullyLoggedIn)
+                .login("{kcLocale: 'en'}", assertLocaleIsSet("en"));
+    }
+    
+    @Test
     public void testRefreshToken() {
         testExecutor.init(defaultArguments(), this::assertInitNotAuth)
                 .refreshToken(9999, assertOutputContains("Failed to refresh token"))
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/javascript/JavascriptTestExecutor.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/javascript/JavascriptTestExecutor.java
index 8db7dee..d856f36 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/javascript/JavascriptTestExecutor.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/javascript/JavascriptTestExecutor.java
@@ -36,11 +36,19 @@ public class JavascriptTestExecutor {
     }
 
     public JavascriptTestExecutor login() {
-        return login(null);
+        return login(null, null);
     }
-
+    
     public JavascriptTestExecutor login(JavascriptStateValidator validator) {
-        jsExecutor.executeScript("keycloak.login()");
+        return login(null, validator);
+    }
+    
+    public JavascriptTestExecutor login(String options, JavascriptStateValidator validator) {
+        if (options == null)
+            jsExecutor.executeScript("keycloak.login()");
+        else {
+            jsExecutor.executeScript("keycloak.login(" + options + ")");
+        }
 
         if (validator != null) {
             validator.validate(jsDriver, output, events);