summaryrefslogtreecommitdiffstats
path: root/toolkit/components/translations/tests/browser/browser_translations_actor_sync_models.js
diff options
context:
space:
mode:
Diffstat (limited to 'toolkit/components/translations/tests/browser/browser_translations_actor_sync_models.js')
-rw-r--r--toolkit/components/translations/tests/browser/browser_translations_actor_sync_models.js235
1 files changed, 235 insertions, 0 deletions
diff --git a/toolkit/components/translations/tests/browser/browser_translations_actor_sync_models.js b/toolkit/components/translations/tests/browser/browser_translations_actor_sync_models.js
new file mode 100644
index 0000000000..1d1877fc38
--- /dev/null
+++ b/toolkit/components/translations/tests/browser/browser_translations_actor_sync_models.js
@@ -0,0 +1,235 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+/**
+ * An actor unit test for testing RemoteSettings update behavior. This uses the
+ * recommendations from:
+ *
+ * https://firefox-source-docs.mozilla.org/services/settings/index.html#unit-tests
+ */
+add_task(async function test_translations_actor_sync_update() {
+ const { remoteClients, cleanup } = await setupActorTest({
+ autoDownloadFromRemoteSettings: true,
+ languagePairs: [
+ { fromLang: "en", toLang: "es" },
+ { fromLang: "es", toLang: "en" },
+ ],
+ });
+
+ const decoder = new TextDecoder();
+ const modelsPromise = TranslationsParent.getLanguageTranslationModelFiles(
+ "en",
+ "es"
+ );
+
+ await remoteClients.translationModels.resolvePendingDownloads(
+ FILES_PER_LANGUAGE_PAIR
+ );
+
+ const oldModels = await modelsPromise;
+
+ is(
+ decoder.decode(oldModels.model.buffer),
+ "Mocked download: test-translation-models model.enes.intgemm.alphas.bin 1.0",
+ "The version 1.0 model is downloaded."
+ );
+
+ const newModelRecords = createRecordsForLanguagePair("en", "es");
+ for (const newModelRecord of newModelRecords) {
+ newModelRecord.version = "1.1";
+ }
+
+ info('Emitting a remote client "sync" event with an updated record.');
+ await remoteClients.translationModels.client.emit("sync", {
+ data: {
+ created: [],
+ updated: newModelRecords.map(newRecord => ({
+ old: oldModels[newRecord.fileType].record,
+ new: newRecord,
+ })),
+ deleted: [],
+ },
+ });
+
+ const updatedModelsPromise =
+ TranslationsParent.getLanguageTranslationModelFiles("en", "es");
+
+ await remoteClients.translationModels.resolvePendingDownloads(
+ FILES_PER_LANGUAGE_PAIR
+ );
+
+ const { model: updatedModel } = await updatedModelsPromise;
+
+ is(
+ decoder.decode(updatedModel.buffer),
+ "Mocked download: test-translation-models model.enes.intgemm.alphas.bin 1.1",
+ "The version 1.1 model is downloaded."
+ );
+
+ return cleanup();
+});
+
+/**
+ * An actor unit test for testing RemoteSettings delete behavior.
+ */
+add_task(async function test_translations_actor_sync_delete() {
+ const { remoteClients, cleanup } = await setupActorTest({
+ autoDownloadFromRemoteSettings: true,
+ languagePairs: [
+ { fromLang: "en", toLang: "es" },
+ { fromLang: "es", toLang: "en" },
+ ],
+ });
+
+ const decoder = new TextDecoder();
+ const modelsPromise = TranslationsParent.getLanguageTranslationModelFiles(
+ "en",
+ "es"
+ );
+
+ await remoteClients.translationModels.resolvePendingDownloads(
+ FILES_PER_LANGUAGE_PAIR
+ );
+
+ const { model } = await modelsPromise;
+
+ is(
+ decoder.decode(model.buffer),
+ "Mocked download: test-translation-models model.enes.intgemm.alphas.bin 1.0",
+ "The version 1.0 model is downloaded."
+ );
+
+ info('Emitting a remote client "sync" event with a deleted record.');
+ await remoteClients.translationModels.client.emit("sync", {
+ data: {
+ created: [],
+ updated: [],
+ deleted: [model.record],
+ },
+ });
+
+ let errorMessage;
+ await TranslationsParent.getLanguageTranslationModelFiles("en", "es").catch(
+ error => {
+ errorMessage = error?.message;
+ }
+ );
+
+ is(
+ errorMessage,
+ 'No model file was found for "en" to "es."',
+ "The model was successfully removed."
+ );
+
+ return cleanup();
+});
+
+/**
+ * An actor unit test for testing RemoteSettings creation behavior.
+ */
+add_task(async function test_translations_actor_sync_create() {
+ const { remoteClients, cleanup } = await setupActorTest({
+ autoDownloadFromRemoteSettings: true,
+ languagePairs: [
+ { fromLang: "en", toLang: "es" },
+ { fromLang: "es", toLang: "en" },
+ ],
+ });
+
+ const decoder = new TextDecoder();
+ const modelsPromise = TranslationsParent.getLanguageTranslationModelFiles(
+ "en",
+ "es"
+ );
+
+ await remoteClients.translationModels.resolvePendingDownloads(
+ FILES_PER_LANGUAGE_PAIR
+ );
+
+ is(
+ decoder.decode((await modelsPromise).model.buffer),
+ "Mocked download: test-translation-models model.enes.intgemm.alphas.bin 1.0",
+ "The version 1.0 model is downloaded."
+ );
+
+ info('Emitting a remote client "sync" event with new records.');
+ await remoteClients.translationModels.client.emit("sync", {
+ data: {
+ created: createRecordsForLanguagePair("en", "fr"),
+ updated: [],
+ deleted: [],
+ },
+ });
+
+ const updatedModelsPromise =
+ TranslationsParent.getLanguageTranslationModelFiles("en", "fr");
+
+ await remoteClients.translationModels.resolvePendingDownloads(
+ FILES_PER_LANGUAGE_PAIR
+ );
+
+ const { vocab, lex, model } = await updatedModelsPromise;
+
+ is(
+ decoder.decode(vocab.buffer),
+ "Mocked download: test-translation-models vocab.enfr.spm 1.0",
+ "The en to fr vocab is downloaded."
+ );
+ is(
+ decoder.decode(lex.buffer),
+ "Mocked download: test-translation-models lex.50.50.enfr.s2t.bin 1.0",
+ "The en to fr lex is downloaded."
+ );
+ is(
+ decoder.decode(model.buffer),
+ "Mocked download: test-translation-models model.enfr.intgemm.alphas.bin 1.0",
+ "The en to fr model is downloaded."
+ );
+
+ return cleanup();
+});
+
+add_task(async function test_translations_parent_download_size() {
+ const { cleanup } = await setupActorTest({
+ languagePairs: [
+ { fromLang: "en", toLang: "es" },
+ { fromLang: "es", toLang: "en" },
+ { fromLang: "en", toLang: "de" },
+ { fromLang: "de", toLang: "en" },
+ ],
+ });
+
+ const directSize =
+ await TranslationsParent.getExpectedTranslationDownloadSize("en", "es");
+ // Includes model, lex, and vocab files (x3), each mocked at 123 bytes.
+ is(
+ directSize,
+ 3 * 123,
+ "Returned the expected download size for a direct translation."
+ );
+
+ const pivotSize = await TranslationsParent.getExpectedTranslationDownloadSize(
+ "es",
+ "de"
+ );
+ // Includes a pivot (x2), model, lex, and vocab files (x3), each mocked at 123 bytes.
+ is(
+ pivotSize,
+ 2 * 3 * 123,
+ "Returned the expected download size for a pivot."
+ );
+
+ const notApplicableSize =
+ await TranslationsParent.getExpectedTranslationDownloadSize(
+ "unknown",
+ "unknown"
+ );
+ is(
+ notApplicableSize,
+ 0,
+ "Returned the expected download size for an unknown or not applicable model."
+ );
+ return cleanup();
+});