/* Any copyright is dedicated to the Public Domain. http://creativecommons.org/publicdomain/zero/1.0/ */ "use strict"; /** * This file contains unit tests for the translations actor. Generally it's preferable * to test behavior in a full integration test, but occasionally it's useful to test * specific implementation behavior. */ /** * Enforce the pivot language behavior in ensureLanguagePairsHavePivots. */ add_task(async function test_pivot_language_behavior() { info( "Expect 4 console.error messages notifying of the lack of a pivot language." ); const { actor, cleanup } = await setupActorTest({ languagePairs: [ { fromLang: "en", toLang: "es", isBeta: false }, { fromLang: "es", toLang: "en", isBeta: false }, { fromLang: "en", toLang: "yue", isBeta: true }, { fromLang: "yue", toLang: "en", isBeta: true }, // This is not a bi-directional translation. { fromLang: "is", toLang: "en", isBeta: false }, // These are non-pivot languages. { fromLang: "zh", toLang: "ja", isBeta: true }, { fromLang: "ja", toLang: "zh", isBeta: true }, ], }); const { languagePairs } = await actor.getSupportedLanguages(); // The pairs aren't guaranteed to be sorted. languagePairs.sort((a, b) => TranslationsParent.languagePairKey(a.fromLang, a.toLang).localeCompare( TranslationsParent.languagePairKey(b.fromLang, b.toLang) ) ); Assert.deepEqual( languagePairs, [ { fromLang: "en", toLang: "es", isBeta: false }, { fromLang: "en", toLang: "yue", isBeta: true }, { fromLang: "es", toLang: "en", isBeta: false }, { fromLang: "is", toLang: "en", isBeta: false }, { fromLang: "yue", toLang: "en", isBeta: true }, ], "Non-pivot languages were removed." ); return cleanup(); }); async function usingAppLocale(locale, callback) { info(`Mocking the locale "${locale}", expect missing resource errors.`); const { availableLocales, requestedLocales } = Services.locale; Services.locale.availableLocales = [locale]; Services.locale.requestedLocales = [locale]; if (Services.locale.appLocaleAsBCP47 !== locale) { throw new Error("Unable to change the app locale."); } await callback(); // Reset back to the originals. Services.locale.availableLocales = availableLocales; Services.locale.requestedLocales = requestedLocales; } add_task(async function test_translating_to_and_from_app_language() { const PIVOT_LANGUAGE = "en"; const { actor, cleanup } = await setupActorTest({ languagePairs: [ { fromLang: PIVOT_LANGUAGE, toLang: "es" }, { fromLang: "es", toLang: PIVOT_LANGUAGE }, { fromLang: PIVOT_LANGUAGE, toLang: "fr" }, { fromLang: "fr", toLang: PIVOT_LANGUAGE }, { fromLang: PIVOT_LANGUAGE, toLang: "pl" }, { fromLang: "pl", toLang: PIVOT_LANGUAGE }, ], }); /** * Each language pair has multiple models. De-duplicate the language pairs and * return a sorted list. */ function getUniqueLanguagePairs(records) { const langPairs = new Set(); for (const { fromLang, toLang } of records) { langPairs.add(TranslationsParent.languagePairKey(fromLang, toLang)); } return Array.from(langPairs) .sort() .map(langPair => { const [fromLang, toLang] = langPair.split(","); return { fromLang, toLang, }; }); } function assertLanguagePairs({ app, requested, message, languagePairs, isForDeletion, }) { return usingAppLocale(app, async () => { Assert.deepEqual( getUniqueLanguagePairs( await actor.getRecordsForTranslatingToAndFromAppLanguage( requested, isForDeletion ) ), languagePairs, message ); }); } await assertLanguagePairs({ message: "When the app locale is the pivot language, download another language.", app: PIVOT_LANGUAGE, requested: "fr", languagePairs: [ { fromLang: PIVOT_LANGUAGE, toLang: "fr" }, { fromLang: "fr", toLang: PIVOT_LANGUAGE }, ], }); await assertLanguagePairs({ message: "When a pivot language is required, they are both downloaded.", app: "fr", requested: "pl", languagePairs: [ { fromLang: PIVOT_LANGUAGE, toLang: "fr" }, { fromLang: PIVOT_LANGUAGE, toLang: "pl" }, { fromLang: "fr", toLang: PIVOT_LANGUAGE }, { fromLang: "pl", toLang: PIVOT_LANGUAGE }, ], }); await assertLanguagePairs({ message: "When downloading the pivot language, only download the one for the app's locale.", app: "es", requested: PIVOT_LANGUAGE, languagePairs: [ { fromLang: PIVOT_LANGUAGE, toLang: "es" }, { fromLang: "es", toLang: PIVOT_LANGUAGE }, ], }); await assertLanguagePairs({ message: "Delete just the requested language when the app locale is the pivot language", app: PIVOT_LANGUAGE, requested: "fr", isForDeletion: true, languagePairs: [ { fromLang: PIVOT_LANGUAGE, toLang: "fr" }, { fromLang: "fr", toLang: PIVOT_LANGUAGE }, ], }); await assertLanguagePairs({ message: "Delete just the requested language, and not the pivot.", app: "fr", requested: "pl", isForDeletion: true, languagePairs: [ { fromLang: PIVOT_LANGUAGE, toLang: "pl" }, { fromLang: "pl", toLang: PIVOT_LANGUAGE }, ], }); await assertLanguagePairs({ message: "Delete just the requested language, and not the pivot.", app: "fr", requested: "pl", isForDeletion: true, languagePairs: [ { fromLang: PIVOT_LANGUAGE, toLang: "pl" }, { fromLang: "pl", toLang: PIVOT_LANGUAGE }, ], }); await assertLanguagePairs({ message: "Delete just the pivot → app and app → pivot.", app: "es", requested: PIVOT_LANGUAGE, isForDeletion: true, languagePairs: [ { fromLang: PIVOT_LANGUAGE, toLang: "es" }, { fromLang: "es", toLang: PIVOT_LANGUAGE }, ], }); await assertLanguagePairs({ message: "If the app and request language are the same, nothing is returned.", app: "fr", requested: "fr", languagePairs: [], }); return cleanup(); });