test_remote_settings_worker.js (3749B)
1 const IS_ANDROID = AppConstants.platform == "android"; 2 3 add_task(async function test_canonicaljson() { 4 const records = [ 5 { id: "1", title: "title 1" }, 6 { id: "2", title: "title 2" }, 7 ]; 8 const timestamp = 42; 9 10 const serialized = await RemoteSettingsWorker.canonicalStringify( 11 records, 12 timestamp 13 ); 14 15 Assert.equal( 16 serialized, 17 '{"data":[{"id":"1","title":"title 1"},{"id":"2","title":"title 2"}],"last_modified":"42"}' 18 ); 19 }); 20 21 add_task(async function test_import_json_dump_into_idb() { 22 if (IS_ANDROID) { 23 // Skip test: we don't ship remote settings dumps on Android (see package-manifest). 24 return; 25 } 26 const client = new RemoteSettingsClient("language-dictionaries"); 27 const before = await client.db.getLastModified(); 28 Assert.equal(before, null); 29 30 await RemoteSettingsWorker.importJSONDump("main", "language-dictionaries"); 31 32 const after = await client.get({ syncIfEmpty: false }); 33 Assert.ok(!!after.length); 34 let lastModifiedStamp = await client.getLastModified(); 35 36 Assert.equal( 37 lastModifiedStamp, 38 Math.max(...after.map(record => record.last_modified)), 39 "Should have correct last modified timestamp" 40 ); 41 42 // Force a DB close for shutdown so we can delete the DB later. 43 Database._shutdownHandler(); 44 }); 45 46 add_task(async function test_throws_error_if_worker_fails() { 47 let error; 48 try { 49 await RemoteSettingsWorker.canonicalStringify(null, 42); 50 } catch (e) { 51 error = e; 52 } 53 Assert.equal(error.message.endsWith("records is null"), true); 54 }); 55 56 add_task(async function test_throws_error_if_worker_fails_async() { 57 if (IS_ANDROID) { 58 // Skip test: we don't ship dump, so importJSONDump() is no-op. 59 return; 60 } 61 // Delete the Remote Settings database, and try to import a dump. 62 // This is not supported, and the error thrown asynchronously in the worker 63 // should be reported to the caller. 64 await new Promise((resolve, reject) => { 65 const request = indexedDB.deleteDatabase("remote-settings"); 66 request.onsuccess = () => resolve(); 67 request.onblocked = () => reject(new Error("Cannot delete DB")); 68 request.onerror = event => reject(event.target.error); 69 }); 70 let error; 71 try { 72 await RemoteSettingsWorker.importJSONDump("main", "language-dictionaries"); 73 } catch (e) { 74 error = e; 75 } 76 Assert.ok(/IndexedDB: Error accessing remote-settings/.test(error.message)); 77 }); 78 79 add_task(async function test_throws_error_if_worker_crashes() { 80 // This simulates a crash at the worker level (not within a promise). 81 let error; 82 try { 83 await RemoteSettingsWorker._execute("unknown_method"); 84 } catch (e) { 85 error = e; 86 } 87 Assert.equal(error.message, "TypeError: Agent[method] is not a function"); 88 }); 89 90 add_task(async function test_stops_worker_after_timeout() { 91 // Change the idle time. 92 Services.prefs.setIntPref( 93 "services.settings.worker_idle_max_milliseconds", 94 1 95 ); 96 // Run a task: 97 let serialized = await RemoteSettingsWorker.canonicalStringify([], 42); 98 Assert.equal(serialized, '{"data":[],"last_modified":"42"}', "API works."); 99 // Check that the worker gets stopped now the task is done: 100 await TestUtils.waitForCondition(() => !RemoteSettingsWorker.worker); 101 // Ensure the worker stays alive for 10 minutes instead: 102 Services.prefs.setIntPref( 103 "services.settings.worker_idle_max_milliseconds", 104 600000 105 ); 106 // Run another task: 107 serialized = await RemoteSettingsWorker.canonicalStringify([], 42); 108 Assert.equal( 109 serialized, 110 '{"data":[],"last_modified":"42"}', 111 "API still works." 112 ); 113 Assert.ok(RemoteSettingsWorker.worker, "Worker should stay alive a bit."); 114 115 // Clear the pref. 116 Services.prefs.clearUserPref( 117 "services.settings.worker_idle_max_milliseconds" 118 ); 119 });