Bug 1479008 - Install related dictionaries after a langpack is installed r=leplatrem,aswan

Differential Revision: https://phabricator.services.mozilla.com/D8442

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Mark Striemer 2018-10-16 20:09:02 +00:00
parent 7e94e1f9a8
commit f63ed672e2
6 changed files with 134 additions and 29 deletions

View File

@ -10,6 +10,24 @@ ChromeUtils.defineModuleGetter(this, "AddonManager",
"resource://gre/modules/AddonManager.jsm");
ChromeUtils.defineModuleGetter(this, "AddonRepository",
"resource://gre/modules/addons/AddonRepository.jsm");
ChromeUtils.defineModuleGetter(this, "RemoteSettings",
"resource://services-settings/remote-settings.js");
async function installFromUrl(url, hash) {
let install = await AddonManager.getInstallForURL(
url, "application/x-xpinstall", hash);
return install.install();
}
async function dictionaryIdsForLocale(locale) {
let entries = await RemoteSettings("language-dictionaries").get({
filters: {id: locale},
});
if (entries.length > 0) {
return entries[0].dictionaries;
}
return [];
}
class OrderedListBox {
constructor({richlistbox, upButton, downButton, removeButton, onRemove}) {
@ -394,37 +412,61 @@ var gBrowserLanguagesDialog = {
},
async availableLanguageSelected(item) {
let available = new Set(Services.locale.availableLocales);
if (available.has(item.value)) {
this._requestedLocales.addItem(item);
if (available.size == this._requestedLocales.items.length) {
// Remove the installed label, they're all installed.
this._availableLocales.items.shift();
this._availableLocales.setItems(this._availableLocales.items);
}
if (Services.locale.availableLocales.includes(item.value)) {
this.requestLocalLanguage(item);
} else if (this.availableLangpacks.has(item.value)) {
this._availableLocales.disableWithMessageId("browser-languages-downloading");
let {url, hash} = this.availableLangpacks.get(item.value);
let install = await AddonManager.getInstallForURL(
url, "application/x-xpinstall", hash);
try {
await install.install();
} catch (e) {
this.showError();
return;
}
item.installed = true;
this._requestedLocales.addItem(item);
this._availableLocales.enableWithMessageId("browser-languages-select-language");
await this.requestRemoteLanguage(item);
} else {
this.showError();
}
},
requestLocalLanguage(item, available) {
this._requestedLocales.addItem(item);
let requestedCount = this._requestedLocales.items.length;
let availableCount = Services.locale.availableLocales.length;
if (requestedCount == availableCount) {
// Remove the installed label, they're all installed.
this._availableLocales.items.shift();
this._availableLocales.setItems(this._availableLocales.items);
}
},
async requestRemoteLanguage(item) {
this._availableLocales.disableWithMessageId(
"browser-languages-downloading");
let {url, hash} = this.availableLangpacks.get(item.value);
try {
await installFromUrl(url, hash);
} catch (e) {
this.showError();
return;
}
item.installed = true;
this._requestedLocales.addItem(item);
this._availableLocales.enableWithMessageId(
"browser-languages-select-language");
// This is an async task that will install the recommended dictionaries for
// this locale. This will fail silently at least until a management UI is
// added in bug 1493705.
this.installDictionariesForLanguage(item.value);
},
async installDictionariesForLanguage(locale) {
try {
let ids = await dictionaryIdsForLocale(locale);
let addonInfos = await AddonRepository.getAddonsByIDs(ids);
await Promise.all(addonInfos.map(
info => installFromUrl(info.sourceURI.spec)));
} catch (e) {
Cu.reportError(e);
}
},
showError() {
document.querySelectorAll(".warning-message-separator")
.forEach(separator => separator.classList.add("thin"));

View File

@ -5,6 +5,7 @@ prefs =
support-files =
head.js
privacypane_tests_perwindow.js
addons/pl-dictionary.xpi
addons/set_homepage.xpi
addons/set_newtab.xpi

View File

@ -4,9 +4,11 @@
ChromeUtils.import("resource://testing-common/AddonTestUtils.jsm", this);
ChromeUtils.import("resource://gre/modules/Services.jsm");
AddonTestUtils.initMochitest(this);
const BROWSER_LANGUAGES_URL = "chrome://browser/content/preferences/browserLanguages.xul";
const DICTIONARY_ID_PL = "pl@dictionaries.addons.mozilla.org";
function getManifestData(locale) {
return {
@ -79,6 +81,45 @@ async function createLanguageToolsFile() {
return dir;
}
async function createDictionaryBrowseResults() {
let testDir = gTestPath.substr(0, gTestPath.lastIndexOf("/"));
let dictionaryPath = testDir + "/addons/pl-dictionary.xpi";
let filename = "dictionaries.json";
let response = {
page_size: 25,
page_count: 1,
count: 1,
results: [{
current_version: {
id: 1823648,
compatibility: {
firefox: {max: "9999", min: "4.0"},
},
files: [{
platform: "all",
url: dictionaryPath,
}],
version: "1.0.20160228",
},
default_locale: "pl",
description: "Polish spell-check",
guid: DICTIONARY_ID_PL,
name: "Polish Dictionary",
slug: "polish-spellchecker-dictionary",
status: "public",
summary: "Polish dictionary",
type: "dictionary",
}],
};
let files = {[filename]: response};
let dir = await AddonTestUtils.promiseWriteFilesToDir(
AddonTestUtils.tempDir.path, files);
dir.append(filename);
return dir;
}
function assertLocaleOrder(list, locales) {
is(list.itemCount, locales.split(",").length,
"The right number of locales are requested");
@ -245,12 +286,16 @@ add_task(async function testInstallFromAMO() {
let langpacksFile = await createLanguageToolsFile();
let langpacksUrl = Services.io.newFileURI(langpacksFile).spec;
let dictionaryBrowseFile = await createDictionaryBrowseResults();
let browseApiEndpoint = Services.io.newFileURI(dictionaryBrowseFile).spec;
await SpecialPowers.pushPrefEnv({
set: [
["intl.multilingual.enabled", true],
["intl.locale.requested", "en-US"],
["extensions.getAddons.langpacks.url", langpacksUrl],
["extensions.langpacks.signatures.required", false],
["extensions.getAddons.get.url", browseApiEndpoint],
],
});
@ -277,6 +322,10 @@ add_task(async function testInstallFromAMO() {
is(Services.locale.availableLocales.join(","),
"en-US", "There is only one installed locale");
// Verify that there are no extra dictionaries.
let dicts = await AddonManager.getAddonsByTypes(["dictionary"]);
is(dicts.length, 0, "There are no installed dictionaries");
// Add Polish, this will install the langpack.
requestLocale("pl", available, dialogDoc);
@ -293,10 +342,21 @@ add_task(async function testInstallFromAMO() {
is(Services.locale.availableLocales.sort().join(","),
"en-US,pl", "Polish is now installed");
// Uninstall the langpack.
langpacks = await AddonManager.getAddonsByTypes(["locale"]);
is(langpacks.length, 1, "There is one langpacks installed");
await Promise.all(langpacks.map(pack => pack.uninstall()));
await BrowserTestUtils.waitForCondition(async () => {
let newDicts = await AddonManager.getAddonsByTypes(["dictionary"]);
let done = newDicts.length != 0;
if (done) {
is(newDicts[0].id, DICTIONARY_ID_PL, "The polish dictionary was installed");
}
return done;
});
// Uninstall the langpack and dictionary.
let installs = await AddonManager.getAddonsByTypes(["locale", "dictionary"]);
is(installs.length, 2, "There is one langpack and one dictionary installed");
await Promise.all(installs.map(item => item.uninstall()));
BrowserTestUtils.removeTab(gBrowser.selectedTab);
});

File diff suppressed because one or more lines are too long

View File

@ -4,6 +4,7 @@
FINAL_TARGET_FILES.defaults.settings.main += [
'example.json',
'language-dictionaries.json',
'onboarding.json',
]