This repository has been archived on 2023-03-18. You can view files and clone it, but cannot push or open issues or pull requests.
osr-discourse-src/app/assets/javascripts/discourse/tests/unit/localization-test.js
Gerhard Schlager 769388b8ba FIX: Translation overrides from fallback locale didn't work on client
Discourse sent only translation overrides for the current language to the client instead of sending overrides from fallback locales as well. This especially impacted en_GB -> en since most overrides would be done in English instead of English (UK).

This also adds lots of tests for previously untested code.

There's a small caveat: The client currently doesn't handle fallback locales for MessageFormat strings. That is why overrides for those strings always have a higher priority than regular translations. So, as an example, the lookup order for MessageFormat strings in German is:
1. override for de
2. override for en
3. value from de
4. value from en
2021-12-17 14:03:35 +01:00

179 lines
5.0 KiB
JavaScript

import { module, test } from "qunit";
import I18n from "I18n";
import LocalizationInitializer from "discourse/initializers/localization";
import { getApplication } from "@ember/test-helpers";
module("initializer:localization", {
_locale: I18n.locale,
_translations: I18n.translations,
_extras: I18n.extras,
_compiledMFs: I18n._compiledMFs,
_overrides: I18n._overrides,
_mfOverrides: I18n._mfOverrides,
beforeEach() {
I18n.locale = "fr";
I18n.translations = {
fr: {
js: {
composer: {
both_languages1: "composer.both_languages1 (FR)",
both_languages2: "composer.both_languages2 (FR)",
},
},
},
en: {
js: {
composer: {
both_languages1: "composer.both_languages1 (EN)",
both_languages2: "composer.both_languages2 (EN)",
only_english1: "composer.only_english1 (EN)",
only_english2: "composer.only_english2 (EN)",
},
},
},
};
I18n._compiledMFs = {
"user.messages.some_key_MF": () => "user.messages.some_key_MF (FR)",
};
I18n.extras = {
fr: {
admin: {
api: {
both_languages1: "admin.api.both_languages1 (FR)",
both_languages2: "admin.api.both_languages2 (FR)",
},
},
},
en: {
admin: {
api: {
both_languages1: "admin.api.both_languages1 (EN)",
both_languages2: "admin.api.both_languages2 (EN)",
only_english1: "admin.api.only_english1 (EN)",
only_english2: "admin.api.only_english2 (EN)",
},
},
},
};
},
afterEach() {
I18n.locale = this._locale;
I18n.translations = this._translations;
I18n.extras = this._extras;
I18n._compiledMFs = this._compiledMFs;
I18n._overrides = this._overrides;
I18n._mfOverrides = this._mfOverrides;
},
});
test("translation overrides", function (assert) {
I18n._overrides = {
fr: {
"js.composer.both_languages1": "composer.both_languages1 (FR override)",
"js.composer.only_english2": "composer.only_english2 (FR override)",
},
en: {
"js.composer.both_languages2": "composer.both_languages2 (EN override)",
"js.composer.only_english1": "composer.only_english1 (EN override)",
},
};
LocalizationInitializer.initialize(getApplication());
assert.strictEqual(
I18n.t("composer.both_languages1"),
"composer.both_languages1 (FR override)",
"overrides existing translation in current locale"
);
assert.strictEqual(
I18n.t("composer.only_english1"),
"composer.only_english1 (EN override)",
"overrides translation in fallback locale"
);
assert.strictEqual(
I18n.t("composer.only_english2"),
"composer.only_english2 (FR override)",
"overrides translation that doesn't exist in current locale"
);
assert.strictEqual(
I18n.t("composer.both_languages2"),
"composer.both_languages2 (FR)",
"prefers translation in current locale over override in fallback locale"
);
});
test("translation overrides (admin_js)", function (assert) {
I18n._overrides = {
fr: {
"admin_js.api.both_languages1": "admin.api.both_languages1 (FR override)",
"admin_js.api.only_english2": "admin.api.only_english2 (FR override)",
},
en: {
"admin_js.api.both_languages2": "admin.api.both_languages2 (EN override)",
"admin_js.api.only_english1": "admin.api.only_english1 (EN override)",
},
};
LocalizationInitializer.initialize(getApplication());
assert.strictEqual(
I18n.t("admin.api.both_languages1"),
"admin.api.both_languages1 (FR override)",
"overrides existing translation in current locale"
);
assert.strictEqual(
I18n.t("admin.api.only_english1"),
"admin.api.only_english1 (EN override)",
"overrides translation in fallback locale"
);
assert.strictEqual(
I18n.t("admin.api.only_english2"),
"admin.api.only_english2 (FR override)",
"overrides translation that doesn't exist in current locale"
);
assert.strictEqual(
I18n.t("admin.api.both_languages2"),
"admin.api.both_languages2 (FR)",
"prefers translation in current locale over override in fallback locale"
);
});
test("translation overrides for MessageFormat strings", function (assert) {
I18n._mfOverrides = {
"js.user.messages.some_key_MF": () =>
"user.messages.some_key_MF (FR override)",
};
LocalizationInitializer.initialize(getApplication());
assert.strictEqual(
I18n.messageFormat("user.messages.some_key_MF", {}),
"user.messages.some_key_MF (FR override)",
"overrides existing MessageFormat string"
);
});
test("skip translation override if parent node is not an object", function (assert) {
I18n._overrides = {
fr: {
"js.composer.both_languages1.foo":
"composer.both_languages1.foo (FR override)",
},
};
LocalizationInitializer.initialize(getApplication());
assert.strictEqual(
I18n.t("composer.both_languages1.foo"),
"[fr.composer.both_languages1.foo]"
);
});