keycloak-scim/js/apps/admin-ui/cypress/e2e/i18n_test.spec.ts
danielFesenmeyer d543ba5b56 Consistent message resolving regarding language fallbacks for all themes
- the prio of messages is now as follows for all themes (RL = realm localization, T = Theme i18n files): RL <variant> > T <variant> > RL <region> > T <region> > RL <language> > T <language> > RL en > T en
- centralize the message resolving logic in helper methods in LocaleUtil and use it for all themes, add unit tests in LocaleUtilTest
- add basic integration tests to check whether realm localization can be used in all supported contexts:
  - Account UI V2: org.keycloak.testsuite.ui.account2.InternationalizationTest
  - Login theme: LoginPageTest
  - Email theme: EmailTest
- deprecate the param useRealmDefaultLocaleFallback=true of endpoint /admin/realms/{realm}/localization/{locale}, because it does not resolve fallbacks as expected and is no longer used in admin-ui v2
- fix locale selection in DefaultLocaleSelectorProvider that a supported region (like "de-CH") will no longer selected instead of a supported language (like "de"), when just the language is requested, add corresponding unit tests
- improvements regarding message resolving in Admin UI V2:
  - add cypress test i18n_test.spec.ts, which checks the fallback implementation
  - log a warning instead of an error, when messages for some languages/namespaces cannot be loaded (the page will probably work with fallbacks in that case)

Closes #15845
2023-05-17 15:00:32 +02:00

178 lines
6.1 KiB
TypeScript

import LoginPage from "../support/pages/LoginPage";
import SidebarPage from "../support/pages/admin-ui/SidebarPage";
import adminClient from "../support/util/AdminClient";
import { keycloakBefore } from "../support/util/keycloak_hooks";
import ProviderPage from "../support/pages/admin-ui/manage/providers/ProviderPage";
import RealmRepresentation from "libs/keycloak-admin-client/lib/defs/realmRepresentation";
const loginPage = new LoginPage();
const sidebarPage = new SidebarPage();
const providersPage = new ProviderPage();
const usernameI18nTest = "user_i18n_test";
let usernameI18nId: string;
let originalMasterRealm: RealmRepresentation;
describe("i18n tests", () => {
before(() => {
cy.wrap(null).then(async () => {
const realm = (await adminClient.getRealm("master"))!;
originalMasterRealm = realm;
realm.supportedLocales = ["en", "de", "de-CH", "fo"];
realm.internationalizationEnabled = true;
await adminClient.updateRealm("master", realm);
const { id: userId } = await adminClient.createUser({
username: usernameI18nTest,
enabled: true,
credentials: [
{ type: "password", temporary: false, value: usernameI18nTest },
],
});
usernameI18nId = userId!;
await adminClient.addRealmRoleToUser(usernameI18nId, "admin");
});
});
after(async () => {
await adminClient.deleteUser(usernameI18nTest);
if (originalMasterRealm) {
await adminClient.updateRealm("master", originalMasterRealm);
}
});
afterEach(async () => {
await adminClient.removeAllLocalizationTexts();
});
const realmLocalizationEn = "realmSettings en";
const themeLocalizationEn = "Realm settings";
const realmLocalizationDe = "realmSettings de";
const themeLocalizationDe = "Realm-Einstellungen";
const realmLocalizationDeCh = "realmSettings de-CH";
it("should use THEME localization for fallback (en) when language without theme localization is requested and no realm localization exists", () => {
updateUserLocale("fo");
goToUserFederationPage();
sidebarPage.checkRealmSettingsLinkContainsText(themeLocalizationEn);
});
it("should use THEME localization for language when language with theme localization is requested and no realm localization exists", () => {
updateUserLocale("de");
goToUserFederationPage();
sidebarPage.checkRealmSettingsLinkContainsText(themeLocalizationDe);
});
it("should use REALM localization for fallback (en) when language without theme localization is requested and realm localization exists for fallback (en)", () => {
addCommonRealmSettingsLocalizationText("en", realmLocalizationEn);
updateUserLocale("fo");
goToUserFederationPage();
sidebarPage.checkRealmSettingsLinkContainsText(realmLocalizationEn);
});
it("should use THEME localization for language when language with theme localization is requested and realm localization exists for fallback (en) only", () => {
addCommonRealmSettingsLocalizationText("en", realmLocalizationEn);
updateUserLocale("de");
goToUserFederationPage();
sidebarPage.checkRealmSettingsLinkContainsText(themeLocalizationDe);
});
it("should use REALM localization for language when language is requested and realm localization exists for language", () => {
addCommonRealmSettingsLocalizationText("de", realmLocalizationDe);
updateUserLocale("de");
goToUserFederationPage();
sidebarPage.checkRealmSettingsLinkContainsText(realmLocalizationDe);
});
// TODO: currently skipped due to https://github.com/keycloak/keycloak/issues/20412
it.skip("should use REALM localization for region when region is requested and realm localization exists for region", () => {
addCommonRealmSettingsLocalizationText("de-CH", realmLocalizationDeCh);
updateUserLocale("de-CH");
goToUserFederationPage();
sidebarPage.checkRealmSettingsLinkContainsText(realmLocalizationDeCh);
});
it("should use REALM localization for language when language is requested and realm localization exists for fallback (en), language, region", () => {
addCommonRealmSettingsLocalizationText("en", realmLocalizationEn);
addCommonRealmSettingsLocalizationText("de", realmLocalizationDe);
addCommonRealmSettingsLocalizationText("de-CH", realmLocalizationDeCh);
updateUserLocale("de");
goToUserFederationPage();
sidebarPage.checkRealmSettingsLinkContainsText(realmLocalizationDe);
});
it("should use REALM localization for language when region is requested and realm localization exists for fallback (en), language", () => {
addCommonRealmSettingsLocalizationText("en", realmLocalizationEn);
addCommonRealmSettingsLocalizationText("de", realmLocalizationDe);
updateUserLocale("de-CH");
goToUserFederationPage();
sidebarPage.checkRealmSettingsLinkContainsText(realmLocalizationDe);
});
it("should apply plurals and interpolation for THEME localization", () => {
updateUserLocale("en");
goToUserFederationPage();
// check key "user-federation:addProvider_other"
providersPage.assertCardContainsText("ldap", "Add Ldap providers");
});
it("should apply plurals and interpolation for REALM localization", () => {
addLocalization(
"en",
"user-federation:addProvider_other",
"addProvider_other en: {{provider}}"
);
updateUserLocale("en");
goToUserFederationPage();
providersPage.assertCardContainsText("ldap", "addProvider_other en: Ldap");
});
function goToUserFederationPage() {
loginPage.logIn(usernameI18nTest, usernameI18nTest);
keycloakBefore();
sidebarPage.goToUserFederation();
}
function updateUserLocale(locale: string) {
cy.wrap(null).then(() =>
adminClient.updateUser(usernameI18nId, { attributes: { locale: locale } })
);
}
function addCommonRealmSettingsLocalizationText(
locale: string,
value: string
) {
addLocalization(locale, "common:realmSettings", value);
}
function addLocalization(locale: string, key: string, value: string) {
cy.wrap(null).then(() =>
adminClient.addLocalizationText(locale, key, value)
);
}
});