diff options
Diffstat (limited to 'services/settings/test/unit/test_remote_settings_worker.js')
-rw-r--r-- | services/settings/test/unit/test_remote_settings_worker.js | 138 |
1 files changed, 138 insertions, 0 deletions
diff --git a/services/settings/test/unit/test_remote_settings_worker.js b/services/settings/test/unit/test_remote_settings_worker.js new file mode 100644 index 0000000000..42b85bb92c --- /dev/null +++ b/services/settings/test/unit/test_remote_settings_worker.js @@ -0,0 +1,138 @@ +/* import-globals-from ../../../common/tests/unit/head_helpers.js */ + +const { AppConstants } = ChromeUtils.importESModule( + "resource://gre/modules/AppConstants.sys.mjs" +); +const { TestUtils } = ChromeUtils.importESModule( + "resource://testing-common/TestUtils.sys.mjs" +); + +const { RemoteSettingsWorker } = ChromeUtils.importESModule( + "resource://services-settings/RemoteSettingsWorker.sys.mjs" +); +const { RemoteSettingsClient } = ChromeUtils.importESModule( + "resource://services-settings/RemoteSettingsClient.sys.mjs" +); +const { Database } = ChromeUtils.importESModule( + "resource://services-settings/Database.sys.mjs" +); + +const IS_ANDROID = AppConstants.platform == "android"; + +add_task(async function test_canonicaljson() { + const records = [ + { id: "1", title: "title 1" }, + { id: "2", title: "title 2" }, + ]; + const timestamp = 42; + + const serialized = await RemoteSettingsWorker.canonicalStringify( + records, + timestamp + ); + + Assert.equal( + serialized, + '{"data":[{"id":"1","title":"title 1"},{"id":"2","title":"title 2"}],"last_modified":"42"}' + ); +}); + +add_task(async function test_import_json_dump_into_idb() { + if (IS_ANDROID) { + // Skip test: we don't ship remote settings dumps on Android (see package-manifest). + return; + } + const client = new RemoteSettingsClient("language-dictionaries"); + const before = await client.get({ syncIfEmpty: false }); + Assert.equal(before.length, 0); + + await RemoteSettingsWorker.importJSONDump("main", "language-dictionaries"); + + const after = await client.get({ syncIfEmpty: false }); + Assert.ok(!!after.length); + let lastModifiedStamp = await client.getLastModified(); + + Assert.equal( + lastModifiedStamp, + Math.max(...after.map(record => record.last_modified)), + "Should have correct last modified timestamp" + ); + + // Force a DB close for shutdown so we can delete the DB later. + Database._shutdownHandler(); +}); + +add_task(async function test_throws_error_if_worker_fails() { + let error; + try { + await RemoteSettingsWorker.canonicalStringify(null, 42); + } catch (e) { + error = e; + } + Assert.equal(error.message.endsWith("records is null"), true); +}); + +add_task(async function test_throws_error_if_worker_fails_async() { + if (IS_ANDROID) { + // Skip test: we don't ship dump, so importJSONDump() is no-op. + return; + } + // Delete the Remote Settings database, and try to import a dump. + // This is not supported, and the error thrown asynchronously in the worker + // should be reported to the caller. + await new Promise((resolve, reject) => { + const request = indexedDB.deleteDatabase("remote-settings"); + request.onsuccess = event => resolve(); + request.onblocked = event => reject(new Error("Cannot delete DB")); + request.onerror = event => reject(event.target.error); + }); + let error; + try { + await RemoteSettingsWorker.importJSONDump("main", "language-dictionaries"); + } catch (e) { + error = e; + } + Assert.ok(/IndexedDB: Error accessing remote-settings/.test(error.message)); +}); + +add_task(async function test_throws_error_if_worker_crashes() { + // This simulates a crash at the worker level (not within a promise). + let error; + try { + await RemoteSettingsWorker._execute("unknown_method"); + } catch (e) { + error = e; + } + Assert.equal(error.message, "TypeError: Agent[method] is not a function"); +}); + +add_task(async function test_stops_worker_after_timeout() { + // Change the idle time. + Services.prefs.setIntPref( + "services.settings.worker_idle_max_milliseconds", + 1 + ); + // Run a task: + let serialized = await RemoteSettingsWorker.canonicalStringify([], 42); + Assert.equal(serialized, '{"data":[],"last_modified":"42"}', "API works."); + // Check that the worker gets stopped now the task is done: + await TestUtils.waitForCondition(() => !RemoteSettingsWorker.worker); + // Ensure the worker stays alive for 10 minutes instead: + Services.prefs.setIntPref( + "services.settings.worker_idle_max_milliseconds", + 600000 + ); + // Run another task: + serialized = await RemoteSettingsWorker.canonicalStringify([], 42); + Assert.equal( + serialized, + '{"data":[],"last_modified":"42"}', + "API still works." + ); + Assert.ok(RemoteSettingsWorker.worker, "Worker should stay alive a bit."); + + // Clear the pref. + Services.prefs.clearUserPref( + "services.settings.worker_idle_max_milliseconds" + ); +}); |