1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/toolkit/mozapps/extensions/test/xpcshell/test_updateCancel.js Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,149 @@ 1.4 +/* Any copyright is dedicated to the Public Domain. 1.5 + * http://creativecommons.org/publicdomain/zero/1.0/ 1.6 + */ 1.7 + 1.8 +// Test cancelling add-on update checks while in progress (bug 925389) 1.9 + 1.10 +Components.utils.import("resource://gre/modules/Promise.jsm"); 1.11 + 1.12 +// The test extension uses an insecure update url. 1.13 +Services.prefs.setBoolPref(PREF_EM_CHECK_UPDATE_SECURITY, false); 1.14 +Services.prefs.setBoolPref(PREF_EM_STRICT_COMPATIBILITY, false); 1.15 + 1.16 +createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "1", "1.9.2"); 1.17 + 1.18 +// Set up an HTTP server to respond to update requests 1.19 +Components.utils.import("resource://testing-common/httpd.js"); 1.20 + 1.21 +const profileDir = gProfD.clone(); 1.22 +profileDir.append("extensions"); 1.23 + 1.24 +// Return a promise that resolves with an addon retrieved by 1.25 +// AddonManager.getAddonByID() 1.26 +function promiseGetAddon(aID) { 1.27 + let p = Promise.defer(); 1.28 + AddonManager.getAddonByID(aID, p.resolve); 1.29 + return p.promise; 1.30 +} 1.31 + 1.32 +function run_test() { 1.33 + // Kick off the task-based tests... 1.34 + run_next_test(); 1.35 +} 1.36 + 1.37 +// Install one extension 1.38 +// Start download of update check (but delay HTTP response) 1.39 +// Cancel update check 1.40 +// - ensure we get cancel notification 1.41 +// complete HTTP response 1.42 +// - ensure no callbacks after cancel 1.43 +// - ensure update is gone 1.44 + 1.45 +// Create an addon update listener containing a promise 1.46 +// that resolves when the update is cancelled 1.47 +function makeCancelListener() { 1.48 + let updated = Promise.defer(); 1.49 + return { 1.50 + onUpdateAvailable: function(addon, install) { 1.51 + updated.reject("Should not have seen onUpdateAvailable notification"); 1.52 + }, 1.53 + 1.54 + onUpdateFinished: function(aAddon, aError) { 1.55 + do_print("onUpdateCheckFinished: " + aAddon.id + " " + aError); 1.56 + updated.resolve(aError); 1.57 + }, 1.58 + promise: updated.promise 1.59 + }; 1.60 +} 1.61 + 1.62 +// Set up the HTTP server so that we can control when it responds 1.63 +let httpReceived = Promise.defer(); 1.64 +function dataHandler(aRequest, aResponse) { 1.65 + asyncResponse = aResponse; 1.66 + aResponse.processAsync(); 1.67 + httpReceived.resolve([aRequest, aResponse]); 1.68 +} 1.69 +var testserver = new HttpServer(); 1.70 +testserver.registerDirectory("/addons/", do_get_file("addons")); 1.71 +testserver.registerPathHandler("/data/test_update.rdf", dataHandler); 1.72 +testserver.start(-1); 1.73 +gPort = testserver.identity.primaryPort; 1.74 + 1.75 +// Set up an add-on for update check 1.76 +writeInstallRDFForExtension({ 1.77 + id: "addon1@tests.mozilla.org", 1.78 + version: "1.0", 1.79 + updateURL: "http://localhost:" + gPort + "/data/test_update.rdf", 1.80 + targetApplications: [{ 1.81 + id: "xpcshell@tests.mozilla.org", 1.82 + minVersion: "1", 1.83 + maxVersion: "1" 1.84 + }], 1.85 + name: "Test Addon 1", 1.86 +}, profileDir); 1.87 + 1.88 +add_task(function cancel_during_check() { 1.89 + startupManager(); 1.90 + 1.91 + let a1 = yield promiseGetAddon("addon1@tests.mozilla.org"); 1.92 + do_check_neq(a1, null); 1.93 + 1.94 + let listener = makeCancelListener(); 1.95 + a1.findUpdates(listener, AddonManager.UPDATE_WHEN_USER_REQUESTED); 1.96 + 1.97 + // Wait for the http request to arrive 1.98 + let [request, response] = yield httpReceived.promise; 1.99 + 1.100 + // cancelUpdate returns true if there is an update check in progress 1.101 + do_check_true(a1.cancelUpdate()); 1.102 + 1.103 + let updateResult = yield listener.promise; 1.104 + do_check_eq(AddonManager.UPDATE_STATUS_CANCELLED, updateResult); 1.105 + 1.106 + // Now complete the HTTP request 1.107 + let file = do_get_cwd(); 1.108 + file.append("data"); 1.109 + file.append("test_update.rdf"); 1.110 + let data = loadFile(file); 1.111 + response.write(data); 1.112 + response.finish(); 1.113 + 1.114 + // trying to cancel again should return false, i.e. nothing to cancel 1.115 + do_check_false(a1.cancelUpdate()); 1.116 + 1.117 + yield true; 1.118 +}); 1.119 + 1.120 +// Test that update check is cancelled if the XPI provider shuts down while 1.121 +// the update check is in progress 1.122 +add_task(function shutdown_during_check() { 1.123 + // Reset our HTTP listener 1.124 + httpReceived = Promise.defer(); 1.125 + 1.126 + let a1 = yield promiseGetAddon("addon1@tests.mozilla.org"); 1.127 + do_check_neq(a1, null); 1.128 + 1.129 + let listener = makeCancelListener(); 1.130 + a1.findUpdates(listener, AddonManager.UPDATE_WHEN_USER_REQUESTED); 1.131 + 1.132 + // Wait for the http request to arrive 1.133 + let [request, response] = yield httpReceived.promise; 1.134 + 1.135 + shutdownManager(); 1.136 + 1.137 + let updateResult = yield listener.promise; 1.138 + do_check_eq(AddonManager.UPDATE_STATUS_CANCELLED, updateResult); 1.139 + 1.140 + // Now complete the HTTP request 1.141 + let file = do_get_cwd(); 1.142 + file.append("data"); 1.143 + file.append("test_update.rdf"); 1.144 + let data = loadFile(file); 1.145 + response.write(data); 1.146 + response.finish(); 1.147 + 1.148 + // trying to cancel again should return false, i.e. nothing to cancel 1.149 + do_check_false(a1.cancelUpdate()); 1.150 + 1.151 + yield testserver.stop(Promise.defer().resolve); 1.152 +});