2008-01-16 13:54:33 -08:00
|
|
|
// Utility functions for offline tests.
|
|
|
|
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
|
|
|
|
|
|
|
|
var Cc = Components.classes;
|
|
|
|
var Ci = Components.interfaces;
|
|
|
|
|
2008-04-08 22:22:32 -07:00
|
|
|
const kNetBase = 2152398848; // 0x804B0000
|
|
|
|
var NS_ERROR_CACHE_KEY_NOT_FOUND = kNetBase + 61;
|
|
|
|
var NS_ERROR_CACHE_KEY_WAIT_FOR_VALIDATION = kNetBase + 64;
|
|
|
|
|
|
|
|
// Reading the contents of multiple cache entries asynchronously
|
|
|
|
function OfflineCacheContents(urls) {
|
|
|
|
this.urls = urls;
|
|
|
|
this.contents = {};
|
|
|
|
}
|
|
|
|
|
|
|
|
OfflineCacheContents.prototype = {
|
|
|
|
QueryInterface: function(iid) {
|
|
|
|
if (!iid.equals(Ci.nsISupports) &&
|
|
|
|
!iid.equals(Ci.nsICacheListener)) {
|
|
|
|
throw Cr.NS_ERROR_NO_INTERFACE;
|
|
|
|
}
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
onCacheEntryAvailable: function(desc, accessGranted, status) {
|
|
|
|
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
|
|
|
|
|
|
|
|
if (!desc) {
|
|
|
|
this.fetch(this.callback);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
var stream = desc.QueryInterface(Ci.nsICacheEntryDescriptor).openInputStream(0);
|
|
|
|
var sstream = Components.classes["@mozilla.org/scriptableinputstream;1"]
|
|
|
|
.createInstance(Components.interfaces.nsIScriptableInputStream);
|
|
|
|
sstream.init(stream);
|
|
|
|
this.contents[desc.key] = sstream.read(sstream.available());
|
|
|
|
sstream.close();
|
|
|
|
desc.close();
|
|
|
|
this.fetch(this.callback);
|
|
|
|
},
|
|
|
|
|
|
|
|
fetch: function(callback)
|
|
|
|
{
|
|
|
|
this.callback = callback;
|
|
|
|
if (this.urls.length == 0) {
|
|
|
|
callback(this.contents);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
var url = this.urls.shift();
|
|
|
|
var self = this;
|
|
|
|
|
2008-08-26 16:09:02 -07:00
|
|
|
var cacheSession = OfflineTest.getActiveSession();
|
2008-04-08 22:22:32 -07:00
|
|
|
cacheSession.asyncOpenCacheEntry(url, Ci.nsICache.ACCESS_READ, this);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2008-01-16 13:54:33 -08:00
|
|
|
var OfflineTest = {
|
|
|
|
|
2010-12-03 09:33:17 -08:00
|
|
|
_hasSlave: false,
|
2008-01-16 13:54:33 -08:00
|
|
|
|
|
|
|
// The window where test results should be sent.
|
|
|
|
_masterWindow: null,
|
|
|
|
|
2008-11-05 16:01:06 -08:00
|
|
|
// Array of all PUT overrides on the server
|
|
|
|
_pathOverrides: [],
|
|
|
|
|
2009-02-18 05:31:30 -08:00
|
|
|
// SJSs whom state was changed to be reverted on teardown
|
|
|
|
_SJSsStated: [],
|
|
|
|
|
2008-01-16 13:54:33 -08:00
|
|
|
setupChild: function()
|
|
|
|
{
|
2010-12-03 09:33:17 -08:00
|
|
|
if (window.parent.OfflineTest._hasSlave) {
|
2008-01-16 13:54:33 -08:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
this._masterWindow = window.top;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
},
|
|
|
|
|
2010-12-07 16:00:19 -08:00
|
|
|
/**
|
|
|
|
* Setup the tests. This will reload the current page in a new window
|
|
|
|
* if necessary.
|
|
|
|
*
|
|
|
|
* @return boolean Whether this window is the slave window
|
|
|
|
* to actually run the test in.
|
|
|
|
*/
|
2008-01-16 13:54:33 -08:00
|
|
|
setup: function()
|
|
|
|
{
|
|
|
|
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
|
|
|
|
|
|
|
|
if (!window.opener || !window.opener.OfflineTest ||
|
2010-12-03 09:33:17 -08:00
|
|
|
!window.opener.OfflineTest._hasSlave) {
|
2008-01-16 13:54:33 -08:00
|
|
|
// Offline applications must be toplevel windows and have the
|
|
|
|
// offline-app permission. Because we were loaded without the
|
|
|
|
// offline-app permission and (probably) in an iframe, we need to
|
|
|
|
// enable the pref and spawn a new window to perform the actual
|
|
|
|
// tests. It will use this window to report successes and
|
|
|
|
// failures.
|
|
|
|
var pm = Cc["@mozilla.org/permissionmanager;1"]
|
|
|
|
.getService(Ci.nsIPermissionManager);
|
|
|
|
var uri = Cc["@mozilla.org/network/io-service;1"]
|
|
|
|
.getService(Ci.nsIIOService)
|
|
|
|
.newURI(window.location.href, null, null);
|
2009-02-25 21:57:28 -08:00
|
|
|
if (pm.testPermission(uri, "offline-app") != 0) {
|
2010-12-07 16:00:19 -08:00
|
|
|
ok(false, "Previous test failed to clear offline-app permission! Expect failures.");
|
2009-02-25 21:57:28 -08:00
|
|
|
}
|
2008-01-16 13:54:33 -08:00
|
|
|
pm.add(uri, "offline-app", Ci.nsIPermissionManager.ALLOW_ACTION);
|
|
|
|
|
|
|
|
// Tests must run as toplevel windows. Open a slave window to run
|
|
|
|
// the test.
|
2010-12-03 09:33:17 -08:00
|
|
|
this._hasSlave = true;
|
|
|
|
window.open(window.location, "offlinetest");
|
2008-01-16 13:54:33 -08:00
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
this._masterWindow = window.opener;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
},
|
|
|
|
|
|
|
|
teardown: function()
|
|
|
|
{
|
|
|
|
// Remove the offline-app permission we gave ourselves.
|
|
|
|
|
|
|
|
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
|
|
|
|
|
|
|
|
var pm = Cc["@mozilla.org/permissionmanager;1"]
|
|
|
|
.getService(Ci.nsIPermissionManager);
|
|
|
|
var uri = Cc["@mozilla.org/network/io-service;1"]
|
|
|
|
.getService(Ci.nsIIOService)
|
|
|
|
.newURI(window.location.href, null, null);
|
|
|
|
pm.remove(uri.host, "offline-app");
|
|
|
|
|
2008-11-05 16:01:06 -08:00
|
|
|
// Clear all overrides on the server
|
|
|
|
for (override in this._pathOverrides)
|
|
|
|
this.deleteData(this._pathOverrides[override]);
|
2009-02-18 05:31:30 -08:00
|
|
|
for (statedSJS in this._SJSsStated)
|
|
|
|
this.setSJSState(this._SJSsStated[statedSJS], "");
|
2008-11-05 16:01:06 -08:00
|
|
|
|
2008-01-16 13:54:33 -08:00
|
|
|
this.clear();
|
|
|
|
},
|
|
|
|
|
|
|
|
finish: function()
|
|
|
|
{
|
|
|
|
if (this._masterWindow) {
|
2010-12-03 09:33:17 -08:00
|
|
|
// Slave window: pass control back to master window, close itself.
|
2010-12-07 16:00:19 -08:00
|
|
|
this._masterWindow.SimpleTest.executeSoon(this._masterWindow.OfflineTest.finish);
|
2008-01-16 13:54:33 -08:00
|
|
|
window.close();
|
2010-12-03 09:33:17 -08:00
|
|
|
} else {
|
|
|
|
// Master window: finish test.
|
|
|
|
SimpleTest.finish();
|
2008-01-16 13:54:33 -08:00
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
//
|
|
|
|
// Mochitest wrappers - These forward tests to the proper mochitest window.
|
|
|
|
//
|
|
|
|
ok: function(condition, name, diag)
|
|
|
|
{
|
|
|
|
return this._masterWindow.SimpleTest.ok(condition, name, diag);
|
|
|
|
},
|
|
|
|
|
|
|
|
is: function(a, b, name)
|
|
|
|
{
|
|
|
|
return this._masterWindow.SimpleTest.is(a, b, name);
|
|
|
|
},
|
|
|
|
|
2008-04-08 22:22:32 -07:00
|
|
|
isnot: function(a, b, name)
|
|
|
|
{
|
|
|
|
return this._masterWindow.SimpleTest.isnot(a, b, name);
|
|
|
|
},
|
|
|
|
|
2008-11-05 16:01:06 -08:00
|
|
|
todo: function(a, name)
|
|
|
|
{
|
|
|
|
return this._masterWindow.SimpleTest.todo(a, name);
|
|
|
|
},
|
|
|
|
|
2008-01-16 13:54:33 -08:00
|
|
|
clear: function()
|
|
|
|
{
|
2008-08-26 16:09:02 -07:00
|
|
|
// XXX: maybe we should just wipe out the entire disk cache.
|
|
|
|
var applicationCache = this.getActiveCache();
|
|
|
|
if (applicationCache) {
|
|
|
|
applicationCache.discard();
|
|
|
|
}
|
2008-01-16 13:54:33 -08:00
|
|
|
},
|
|
|
|
|
|
|
|
failEvent: function(e)
|
|
|
|
{
|
|
|
|
OfflineTest.ok(false, "Unexpected event: " + e.type);
|
|
|
|
},
|
|
|
|
|
|
|
|
// The offline API as specified has no way to watch the load of a resource
|
2009-01-29 07:22:53 -08:00
|
|
|
// added with applicationCache.mozAdd().
|
2008-01-16 13:54:33 -08:00
|
|
|
waitForAdd: function(url, onFinished) {
|
|
|
|
// Check every half second for ten seconds.
|
|
|
|
var numChecks = 20;
|
|
|
|
var waitFunc = function() {
|
2008-08-26 16:09:02 -07:00
|
|
|
var cacheSession = OfflineTest.getActiveSession();
|
2008-01-16 13:54:33 -08:00
|
|
|
var entry;
|
|
|
|
try {
|
2010-12-07 16:00:19 -08:00
|
|
|
entry = cacheSession.openCacheEntry(url, Ci.nsICache.ACCESS_READ, false);
|
2008-01-16 13:54:33 -08:00
|
|
|
} catch (e) {
|
|
|
|
}
|
|
|
|
|
|
|
|
if (entry) {
|
|
|
|
entry.close();
|
|
|
|
onFinished();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (--numChecks == 0) {
|
|
|
|
onFinished();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
setTimeout(OfflineTest.priv(waitFunc), 500);
|
|
|
|
}
|
|
|
|
|
|
|
|
setTimeout(this.priv(waitFunc), 500);
|
|
|
|
},
|
|
|
|
|
|
|
|
getManifestUrl: function()
|
|
|
|
{
|
|
|
|
return window.top.document.documentElement.getAttribute("manifest");
|
|
|
|
},
|
|
|
|
|
2008-08-26 16:09:02 -07:00
|
|
|
getActiveCache: function()
|
|
|
|
{
|
|
|
|
// Note that this is the current active cache in the cache stack, not the
|
|
|
|
// one associated with this window.
|
|
|
|
var serv = Cc["@mozilla.org/network/application-cache-service;1"]
|
|
|
|
.getService(Ci.nsIApplicationCacheService);
|
|
|
|
return serv.getActiveCache(this.getManifestUrl());
|
|
|
|
},
|
|
|
|
|
|
|
|
getActiveSession: function()
|
|
|
|
{
|
|
|
|
var cache = this.getActiveCache();
|
2010-12-07 16:00:19 -08:00
|
|
|
if (!cache)
|
|
|
|
return null;
|
2008-08-26 16:09:02 -07:00
|
|
|
|
|
|
|
var cacheService = Cc["@mozilla.org/network/cache-service;1"]
|
|
|
|
.getService(Ci.nsICacheService);
|
|
|
|
return cacheService.createSession(cache.clientID,
|
|
|
|
Ci.nsICache.STORE_OFFLINE,
|
|
|
|
true);
|
|
|
|
},
|
|
|
|
|
2008-01-16 13:54:33 -08:00
|
|
|
priv: function(func)
|
|
|
|
{
|
|
|
|
var self = this;
|
|
|
|
return function() {
|
|
|
|
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
|
2008-04-08 22:22:32 -07:00
|
|
|
func(arguments);
|
2008-01-16 13:54:33 -08:00
|
|
|
}
|
|
|
|
},
|
|
|
|
|
2008-11-05 16:01:06 -08:00
|
|
|
checkCustomCache: function(group, url, expectEntry)
|
|
|
|
{
|
|
|
|
var serv = Cc["@mozilla.org/network/application-cache-service;1"]
|
|
|
|
.getService(Ci.nsIApplicationCacheService);
|
|
|
|
var cache = serv.getActiveCache(group);
|
|
|
|
var cacheSession = null;
|
|
|
|
if (cache) {
|
|
|
|
var cacheService = Cc["@mozilla.org/network/cache-service;1"]
|
|
|
|
.getService(Ci.nsICacheService);
|
|
|
|
cacheSession = cacheService.createSession(cache.clientID,
|
|
|
|
Ci.nsICache.STORE_OFFLINE,
|
|
|
|
true);
|
|
|
|
}
|
|
|
|
|
|
|
|
this._checkCache(cacheSession, url, expectEntry);
|
|
|
|
},
|
|
|
|
|
2008-01-16 13:54:33 -08:00
|
|
|
checkCache: function(url, expectEntry)
|
|
|
|
{
|
2008-08-26 16:09:02 -07:00
|
|
|
var cacheSession = this.getActiveSession();
|
2008-11-05 16:01:06 -08:00
|
|
|
this._checkCache(cacheSession, url, expectEntry);
|
|
|
|
},
|
|
|
|
|
|
|
|
_checkCache: function(cacheSession, url, expectEntry)
|
|
|
|
{
|
2008-08-26 16:09:02 -07:00
|
|
|
if (!cacheSession) {
|
|
|
|
if (expectEntry) {
|
|
|
|
this.ok(false, url + " should exist in the offline cache");
|
|
|
|
} else {
|
|
|
|
this.ok(true, url + " should not exist in the offline cache");
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2008-01-16 13:54:33 -08:00
|
|
|
try {
|
2008-04-08 22:22:32 -07:00
|
|
|
var entry = cacheSession.openCacheEntry(url, Ci.nsICache.ACCESS_READ, false);
|
2008-01-16 13:54:33 -08:00
|
|
|
if (expectEntry) {
|
|
|
|
this.ok(true, url + " should exist in the offline cache");
|
|
|
|
} else {
|
|
|
|
this.ok(false, url + " should not exist in the offline cache");
|
|
|
|
}
|
|
|
|
entry.close();
|
|
|
|
} catch (e) {
|
|
|
|
if (e.result == NS_ERROR_CACHE_KEY_NOT_FOUND) {
|
|
|
|
if (expectEntry) {
|
|
|
|
this.ok(false, url + " should exist in the offline cache");
|
|
|
|
} else {
|
|
|
|
this.ok(true, url + " should not exist in the offline cache");
|
|
|
|
}
|
2008-08-26 16:09:02 -07:00
|
|
|
} else if (e.result == NS_ERROR_CACHE_KEY_WAIT_FOR_VALIDATION) {
|
2008-04-08 22:22:32 -07:00
|
|
|
// There was a cache key that we couldn't access yet, that's good enough.
|
|
|
|
if (expectEntry) {
|
2008-11-05 16:01:08 -08:00
|
|
|
this.ok(!mustBeValid, url + " should exist in the offline cache");
|
2008-04-08 22:22:32 -07:00
|
|
|
} else {
|
2008-11-05 16:01:08 -08:00
|
|
|
this.ok(mustBeValid, url + " should not exist in the offline cache");
|
2008-04-08 22:22:32 -07:00
|
|
|
}
|
2008-01-16 13:54:33 -08:00
|
|
|
} else {
|
|
|
|
throw e;
|
|
|
|
}
|
|
|
|
}
|
2008-11-05 16:01:06 -08:00
|
|
|
},
|
|
|
|
|
2009-02-18 05:31:30 -08:00
|
|
|
setSJSState: function(sjsPath, stateQuery)
|
2008-11-05 16:01:06 -08:00
|
|
|
{
|
|
|
|
var client = new XMLHttpRequest();
|
2009-02-18 05:31:30 -08:00
|
|
|
client.open("GET", sjsPath + "?state=" + stateQuery, false);
|
2008-11-05 16:01:06 -08:00
|
|
|
|
2009-02-18 05:31:30 -08:00
|
|
|
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
|
|
|
|
var appcachechannel = client.channel.QueryInterface(Ci.nsIApplicationCacheChannel);
|
|
|
|
appcachechannel.chooseApplicationCache = false;
|
|
|
|
appcachechannel.inheritApplicationCache = false;
|
|
|
|
appcachechannel.applicationCache = null;
|
2008-11-05 16:01:06 -08:00
|
|
|
|
|
|
|
client.send();
|
2009-02-18 05:31:30 -08:00
|
|
|
|
|
|
|
if (stateQuery == "")
|
|
|
|
delete this._SJSsStated[sjsPath];
|
|
|
|
else
|
|
|
|
this._SJSsStated.push(sjsPath);
|
2008-01-16 13:54:33 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
};
|