1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
|
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/
*/
// Test how update window behaves when metadata ping times out
// bug 965788
const URI_EXTENSION_UPDATE_DIALOG = "chrome://mozapps/content/extensions/update.xul";
const PREF_GETADDONS_BYIDS = "extensions.getAddons.get.url";
const PREF_MIN_PLATFORM_COMPAT = "extensions.minCompatiblePlatformVersion";
const PREF_METADATA_LASTUPDATE = "extensions.getAddons.cache.lastUpdate";
Components.utils.import("resource://gre/modules/Promise.jsm");
var repo = {};
var ARContext = Components.utils.import("resource://gre/modules/addons/AddonRepository.jsm", repo);
// Mock out the XMLHttpRequest factory for AddonRepository so
// we can reply with a timeout
var pXHRStarted = Promise.defer();
var oldXHRConstructor = ARContext.ServiceRequest;
ARContext.ServiceRequest = function() {
this._handlers = new Map();
this.mozBackgroundRequest = false;
this.timeout = undefined;
this.open = function(aMethod, aURI, aAsync) {
this.method = aMethod;
this.uri = aURI;
this.async = aAsync;
info("Opened XHR for " + aMethod + " " + aURI);
};
this.overrideMimeType = function(aMimeType) {
this.mimeType = aMimeType;
};
this.addEventListener = function(aEvent, aHandler, aCapture) {
this._handlers.set(aEvent, aHandler);
};
this.send = function(aBody) {
info("Send XHR for " + this.method + " " + this.uri + " handlers: " + [this._handlers.keys()].join(", "));
pXHRStarted.resolve(this);
}
};
// Returns promise{window}, resolves with a handle to the compatibility
// check window
function promise_open_compatibility_window(aInactiveAddonIds) {
let deferred = Promise.defer();
// This will reset the longer timeout multiplier to 2 which will give each
// test that calls open_compatibility_window a minimum of 60 seconds to
// complete.
requestLongerTimeout(2);
var variant = Cc["@mozilla.org/variant;1"].
createInstance(Ci.nsIWritableVariant);
variant.setFromVariant(aInactiveAddonIds);
// Cannot be modal as we want to interract with it, shouldn't cause problems
// with testing though.
var features = "chrome,centerscreen,dialog,titlebar";
var ww = Cc["@mozilla.org/embedcomp/window-watcher;1"].
getService(Ci.nsIWindowWatcher);
var win = ww.openWindow(null, URI_EXTENSION_UPDATE_DIALOG, "", features, variant);
win.addEventListener("load", function() {
function page_shown(aEvent) {
if (aEvent.target.pageid)
info("Page " + aEvent.target.pageid + " shown");
}
win.removeEventListener("load", arguments.callee, false);
info("Compatibility dialog opened");
win.addEventListener("pageshow", page_shown, false);
win.addEventListener("unload", function() {
win.removeEventListener("unload", arguments.callee, false);
win.removeEventListener("pageshow", page_shown, false);
dump("Compatibility dialog closed\n");
}, false);
deferred.resolve(win);
}, false);
return deferred.promise;
}
function promise_window_close(aWindow) {
let deferred = Promise.defer();
aWindow.addEventListener("unload", function() {
aWindow.removeEventListener("unload", arguments.callee, false);
deferred.resolve(aWindow);
}, false);
return deferred.promise;
}
// Start the compatibility update dialog, but use the mock XHR to respond with
// a timeout
add_task(function* amo_ping_timeout() {
Services.prefs.setBoolPref(PREF_GETADDONS_CACHE_ENABLED, true);
Services.prefs.clearUserPref(PREF_METADATA_LASTUPDATE);
let compatWindow = yield promise_open_compatibility_window([]);
let xhr = yield pXHRStarted.promise;
is(xhr.timeout, 30000, "XHR request should have 30 second timeout");
ok(xhr._handlers.has("timeout"), "Timeout handler set on XHR");
// call back the timeout handler
xhr._handlers.get("timeout")();
// Put the old XHR constructor back
ARContext.ServiceRequest = oldXHRConstructor;
// The window should close without further interaction
yield promise_window_close(compatWindow);
});
|