diff --git a/toolkit/components/extensions/Extension.jsm b/toolkit/components/extensions/Extension.jsm index ee1562a6e251..ff4319903db3 100644 --- a/toolkit/components/extensions/Extension.jsm +++ b/toolkit/components/extensions/Extension.jsm @@ -1685,7 +1685,7 @@ this.Langpack = class extends ExtensionData { // Check if there's a root directory `/localization` in the langpack. // If there is one, add it with the name `toolkit` as a FileSource. - const entries = await this.readDirectory("./localization"); + const entries = await this.readDirectory("localization"); if (entries.length > 0) { l10nRegistrySources.toolkit = ""; } @@ -1729,6 +1729,9 @@ this.Langpack = class extends ExtensionData { `resource://${this.langpackId}/${basePath}localization/{locale}/` )); } + + Services.obs.notifyObservers({wrappedJSObject: {langpack: this}}, + "webextension-langpack-startup"); } async shutdown(reason) { diff --git a/toolkit/mozapps/extensions/test/addons/langpack_1/browser/localization/und/browser.ftl b/toolkit/mozapps/extensions/test/addons/langpack_1/browser/localization/und/browser.ftl new file mode 100644 index 000000000000..e1ee61f7b31b --- /dev/null +++ b/toolkit/mozapps/extensions/test/addons/langpack_1/browser/localization/und/browser.ftl @@ -0,0 +1 @@ +message-browser = Value from Browser diff --git a/toolkit/mozapps/extensions/test/addons/langpack_1/chrome/und/locale/und/global/test.properties b/toolkit/mozapps/extensions/test/addons/langpack_1/chrome/und/locale/und/global/test.properties new file mode 100644 index 000000000000..509cb29e4745 --- /dev/null +++ b/toolkit/mozapps/extensions/test/addons/langpack_1/chrome/und/locale/und/global/test.properties @@ -0,0 +1 @@ +message = Value from .properties diff --git a/toolkit/mozapps/extensions/test/addons/langpack_1/localization/und/toolkit_test.ftl b/toolkit/mozapps/extensions/test/addons/langpack_1/localization/und/toolkit_test.ftl new file mode 100644 index 000000000000..643abd059d04 --- /dev/null +++ b/toolkit/mozapps/extensions/test/addons/langpack_1/localization/und/toolkit_test.ftl @@ -0,0 +1 @@ +message-id1 = Value 1 diff --git a/toolkit/mozapps/extensions/test/addons/langpack_1/manifest.json b/toolkit/mozapps/extensions/test/addons/langpack_1/manifest.json new file mode 100644 index 000000000000..d2b0c9b1ba3a --- /dev/null +++ b/toolkit/mozapps/extensions/test/addons/langpack_1/manifest.json @@ -0,0 +1,29 @@ +{ + "name": "und Language Pack", + "version": "1.0", + "manifest_version": 2, + "applications": { + "gecko": { + "id": "langpack-und@test.mozilla.org", + "strict_min_version": "58.0", + "strict_max_version": "58.*" + } + }, + "sources": { + "browser": { + "base_path": "browser/" + } + }, + "langpack_id": "und", + "version": "1", + "languages": { + "und": { + "chrome_resources": { + "global": "chrome/und/locale/und/global/" + }, + "version": "20171001190118" + } + }, + "author": "Mozilla Localization Task Force", + "description": "Language pack for Testy for und" +} diff --git a/toolkit/mozapps/extensions/test/xpcshell/test_webextension_langpack.js b/toolkit/mozapps/extensions/test/xpcshell/test_webextension_langpack.js new file mode 100644 index 000000000000..8c0873563af7 --- /dev/null +++ b/toolkit/mozapps/extensions/test/xpcshell/test_webextension_langpack.js @@ -0,0 +1,131 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ + */ + +Components.utils.import("resource://gre/modules/AppConstants.jsm"); + +const { Services } = Components.utils.import("resource://gre/modules/Services.jsm", {}); +const { L10nRegistry } = Components.utils.import("resource://gre/modules/L10nRegistry.jsm", {}); + +const ID = "langpack-und@test.mozilla.org"; + +const profileDir = gProfD.clone(); +profileDir.append("extensions"); + +createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "1", "58"); +startupManager(); + +function promiseLangpackStartup() { + return new Promise(resolve => { + const EVENT = "webextension-langpack-startup"; + Services.obs.addObserver(function observer() { + Services.obs.removeObserver(observer, EVENT); + resolve(); + }, EVENT); + }); +} + +/** + * This is a basic life-cycle test which verifies that + * the language pack registers and unregisters correct + * languages at various stages. + */ +add_task(async function() { + // Make sure that `und` locale is not installed. + equal(L10nRegistry.getAvailableLocales().includes("und"), false); + equal(Services.locale.getAvailableLocales().includes("und"), false); + + let [{addon}, ] = await Promise.all([ + promiseInstallFile(do_get_addon("langpack_1"), true), + promiseLangpackStartup() + ]); + + // Now make sure that `und` locale is available. + equal(L10nRegistry.getAvailableLocales().includes("und"), true); + equal(Services.locale.getAvailableLocales().includes("und"), true); + + addon.userDisabled = true; + + // It is not available after the langpack has been disabled. + equal(L10nRegistry.getAvailableLocales().includes("und"), false); + equal(Services.locale.getAvailableLocales().includes("und"), false); + + addon.userDisabled = false; + await promiseLangpackStartup(); + + // After re-enabling it, the `und` locale is available again. + equal(L10nRegistry.getAvailableLocales().includes("und"), true); + equal(Services.locale.getAvailableLocales().includes("und"), true); + + addon.uninstall(); + + // After the langpack has been uninstalled, no more `und` in locales. + equal(L10nRegistry.getAvailableLocales().includes("und"), false); + equal(Services.locale.getAvailableLocales().includes("und"), false); +}); + +/** + * This test verifies that registries are able to load and return + * correct strings available in the language pack. + */ +add_task(async function() { + let [{addon}, ] = await Promise.all([ + promiseInstallFile(do_get_addon("langpack_1"), true), + promiseLangpackStartup() + ]); + + { + // Toolkit string + let ctxs = L10nRegistry.generateContexts(["und"], ["toolkit_test.ftl"]); + let ctx0 = (await ctxs.next()).value; + equal(ctx0.hasMessage("message-id1"), true); + } + + { + // Browser string + let ctxs = L10nRegistry.generateContexts(["und"], ["browser.ftl"]); + let ctx0 = (await ctxs.next()).value; + equal(ctx0.hasMessage("message-browser"), true); + } + + { + // Test chrome package + let reqLocs = Services.locale.getRequestedLocales(); + Services.locale.setRequestedLocales(["und"]); + + let bundle = Services.strings.createBundle( + "chrome://global/locale/test.properties" + ); + let entry = bundle.GetStringFromName("message"); + equal(entry, "Value from .properties"); + + Services.locale.setRequestedLocales(reqLocs); + } + + addon.uninstall(); +}); + +/** + * This test verifies that language pack will get disabled after app + * gets upgraded. + */ +add_task(async function() { + let [{addon}, ] = await Promise.all([ + promiseInstallFile(do_get_addon("langpack_1"), true), + promiseLangpackStartup() + ]); + do_check_true(addon.isActive); + + await promiseShutdownManager(); + + gAppInfo.version = "59"; + gAppInfo.platformVersion = "59"; + + await promiseStartupManager(true); + + addon = await promiseAddonByID(ID); + do_check_false(addon.isActive); + do_check_true(addon.appDisabled); + + addon.uninstall(); +}); diff --git a/toolkit/mozapps/extensions/test/xpcshell/xpcshell-shared.ini b/toolkit/mozapps/extensions/test/xpcshell/xpcshell-shared.ini index 5d51609ea5ef..56300c997320 100644 --- a/toolkit/mozapps/extensions/test/xpcshell/xpcshell-shared.ini +++ b/toolkit/mozapps/extensions/test/xpcshell/xpcshell-shared.ini @@ -331,6 +331,9 @@ tags = webextensions [test_webextension_embedded.js] skip-if = appname == "thunderbird" tags = webextensions +[test_webextension_langpack.js] +skip-if = appname == "thunderbird" +tags = webextensions [test_webextension_install_syntax_error.js] skip-if = appname == "thunderbird" tags = webextensions