michael@0: /* Any copyright is dedicated to the Public Domain. michael@0: * http://creativecommons.org/publicdomain/zero/1.0/ michael@0: */ michael@0: michael@0: // Test how update window behaves when metadata ping times out michael@0: // bug 965788 michael@0: michael@0: const URI_EXTENSION_UPDATE_DIALOG = "chrome://mozapps/content/extensions/update.xul"; michael@0: michael@0: const PREF_GETADDONS_BYIDS = "extensions.getAddons.get.url"; michael@0: const PREF_MIN_PLATFORM_COMPAT = "extensions.minCompatiblePlatformVersion"; michael@0: michael@0: Components.utils.import("resource://gre/modules/Promise.jsm"); michael@0: michael@0: let repo = {}; michael@0: let ARContext = Components.utils.import("resource://gre/modules/addons/AddonRepository.jsm", repo); michael@0: info("ARContext: " + Object.keys(ARContext).join(", ")); michael@0: michael@0: // Mock out the XMLHttpRequest factory for AddonRepository so michael@0: // we can reply with a timeout michael@0: let pXHRStarted = Promise.defer(); michael@0: let oldXHRConstructor = ARContext.XHRequest; michael@0: ARContext.XHRequest = function() { michael@0: this._handlers = new Map(); michael@0: this.mozBackgroundRequest = false; michael@0: this.timeout = undefined; michael@0: this.open = function(aMethod, aURI, aAsync) { michael@0: this.method = aMethod; michael@0: this.uri = aURI; michael@0: this.async = aAsync; michael@0: info("Opened XHR for " + aMethod + " " + aURI); michael@0: }; michael@0: this.overrideMimeType = function(aMimeType) { michael@0: this.mimeType = aMimeType; michael@0: }; michael@0: this.addEventListener = function(aEvent, aHandler, aCapture) { michael@0: this._handlers.set(aEvent, aHandler); michael@0: }; michael@0: this.send = function(aBody) { michael@0: info("Send XHR for " + this.method + " " + this.uri + " handlers: " + [this._handlers.keys()].join(", ")); michael@0: pXHRStarted.resolve(this); michael@0: } michael@0: }; michael@0: michael@0: michael@0: // Returns promise{window}, resolves with a handle to the compatibility michael@0: // check window michael@0: function promise_open_compatibility_window(aInactiveAddonIds) { michael@0: let deferred = Promise.defer(); michael@0: // This will reset the longer timeout multiplier to 2 which will give each michael@0: // test that calls open_compatibility_window a minimum of 60 seconds to michael@0: // complete. michael@0: requestLongerTimeout(100 /* XXX was 2 */); michael@0: michael@0: var variant = Cc["@mozilla.org/variant;1"]. michael@0: createInstance(Ci.nsIWritableVariant); michael@0: variant.setFromVariant(aInactiveAddonIds); michael@0: michael@0: // Cannot be modal as we want to interract with it, shouldn't cause problems michael@0: // with testing though. michael@0: var features = "chrome,centerscreen,dialog,titlebar"; michael@0: var ww = Cc["@mozilla.org/embedcomp/window-watcher;1"]. michael@0: getService(Ci.nsIWindowWatcher); michael@0: var win = ww.openWindow(null, URI_EXTENSION_UPDATE_DIALOG, "", features, variant); michael@0: michael@0: win.addEventListener("load", function() { michael@0: function page_shown(aEvent) { michael@0: if (aEvent.target.pageid) michael@0: info("Page " + aEvent.target.pageid + " shown"); michael@0: } michael@0: michael@0: win.removeEventListener("load", arguments.callee, false); michael@0: michael@0: info("Compatibility dialog opened"); michael@0: michael@0: win.addEventListener("pageshow", page_shown, false); michael@0: win.addEventListener("unload", function() { michael@0: win.removeEventListener("unload", arguments.callee, false); michael@0: win.removeEventListener("pageshow", page_shown, false); michael@0: dump("Compatibility dialog closed\n"); michael@0: }, false); michael@0: michael@0: deferred.resolve(win); michael@0: }, false); michael@0: return deferred.promise; michael@0: } michael@0: michael@0: function promise_window_close(aWindow) { michael@0: let deferred = Promise.defer(); michael@0: aWindow.addEventListener("unload", function() { michael@0: aWindow.removeEventListener("unload", arguments.callee, false); michael@0: deferred.resolve(aWindow); michael@0: }, false); michael@0: return deferred.promise; michael@0: } michael@0: michael@0: // Start the compatibility update dialog, but use the mock XHR to respond with michael@0: // a timeout michael@0: add_task(function* amo_ping_timeout() { michael@0: Services.prefs.setBoolPref(PREF_GETADDONS_CACHE_ENABLED, true); michael@0: let compatWindow = yield promise_open_compatibility_window([]); michael@0: michael@0: let xhr = yield pXHRStarted.promise; michael@0: is(xhr.timeout, 30000, "XHR request should have 30 second timeout"); michael@0: ok(xhr._handlers.has("timeout"), "Timeout handler set on XHR"); michael@0: // call back the timeout handler michael@0: xhr._handlers.get("timeout")(); michael@0: michael@0: // Put the old XHR constructor back michael@0: ARContext.XHRequest = oldXHRConstructor; michael@0: // The window should close without further interaction michael@0: yield promise_window_close(compatWindow); michael@0: });