forked from mirrors/gecko-dev
347 lines
12 KiB
JavaScript
347 lines
12 KiB
JavaScript
/*
|
|
* Bug 1238183 - Test cases for forgetAboutSite with userContextId.
|
|
*/
|
|
|
|
const { classes: Cc, Constructor: CC, interfaces: Ci, utils: Cu } = Components;
|
|
|
|
Cu.import("resource://gre/modules/ForgetAboutSite.jsm");
|
|
Cu.import("resource://gre/modules/Services.jsm");
|
|
let {HttpServer} = Cu.import("resource://testing-common/httpd.js", {});
|
|
let LoadContextInfo = Cc["@mozilla.org/load-context-info-factory;1"]
|
|
.getService(Ci.nsILoadContextInfoFactory);
|
|
let css = Cc["@mozilla.org/netwerk/cache-storage-service;1"]
|
|
.getService(Ci.nsICacheStorageService);
|
|
|
|
const USER_CONTEXTS = [
|
|
"default",
|
|
"personal",
|
|
];
|
|
const TEST_HOST = "example.com";
|
|
const TEST_URL = "http://" + TEST_HOST + "/browser/browser/components/contextualidentity/test/browser/";
|
|
const COOKIE_NAME = "userContextId";
|
|
|
|
// Counter for image load hits.
|
|
let gHits = 0;
|
|
|
|
let gHttpServer = null;
|
|
|
|
function imageHandler(metadata, response) {
|
|
// A 1x1 PNG image.
|
|
// Source: https://commons.wikimedia.org/wiki/File:1x1.png (Public Domain)
|
|
const IMAGE = atob("iVBORw0KGgoAAAANSUhEUgAAAAEAAAABAQMAAAAl21bKAAAAA1BMVEUAA" +
|
|
"ACnej3aAAAAAXRSTlMAQObYZgAAAApJREFUCNdjYAAAAAIAAeIhvDMAAAAASUVORK5CYII=");
|
|
gHits++;
|
|
response.setHeader("Cache-Control", "max-age=10000", false);
|
|
response.setStatusLine(metadata.httpVersion, 200, "OK");
|
|
response.setHeader("Content-Type", "image/png", false);
|
|
response.write(IMAGE);
|
|
}
|
|
|
|
function loadImagePageHandler(metadata, response) {
|
|
response.setHeader("Cache-Control", "max-age=10000", false);
|
|
response.setStatusLine(metadata.httpVersion, 200, "Ok");
|
|
response.setHeader("Content-Type", "text/html", false);
|
|
let body = "<!DOCTYPE HTML>\
|
|
<html>\
|
|
<head>\
|
|
<meta charset='utf-8'>\
|
|
<title>Load Image</title>\
|
|
</head>\
|
|
<body>\
|
|
<img src='image.png'>\
|
|
</body>\
|
|
</html>";
|
|
response.bodyOutputStream.write(body, body.length);
|
|
}
|
|
|
|
async function openTabInUserContext(uri, userContextId) {
|
|
// Open the tab in the correct userContextId.
|
|
let tab = BrowserTestUtils.addTab(gBrowser, uri, {userContextId});
|
|
|
|
// Select tab and make sure its browser is focused.
|
|
gBrowser.selectedTab = tab;
|
|
tab.ownerGlobal.focus();
|
|
|
|
let browser = gBrowser.getBrowserForTab(tab);
|
|
await BrowserTestUtils.browserLoaded(browser);
|
|
return {tab, browser};
|
|
}
|
|
|
|
function getCookiesForOA(host, userContextId) {
|
|
return Services.cookies.getCookiesFromHost(host, {userContextId});
|
|
}
|
|
|
|
function createURI(uri) {
|
|
let ioServ = Cc["@mozilla.org/network/io-service;1"]
|
|
.getService(Components.interfaces.nsIIOService);
|
|
return ioServ.newURI(uri);
|
|
}
|
|
|
|
function getCacheStorage(where, lci, appcache) {
|
|
if (!lci) lci = LoadContextInfo.default;
|
|
switch (where) {
|
|
case "disk": return css.diskCacheStorage(lci, false);
|
|
case "memory": return css.memoryCacheStorage(lci);
|
|
case "appcache": return css.appCacheStorage(lci, appcache);
|
|
case "pin": return css.pinningCacheStorage(lci);
|
|
}
|
|
return null;
|
|
}
|
|
|
|
function OpenCacheEntry(key, where, flags, lci) {
|
|
return new Promise(resolve => {
|
|
key = createURI(key);
|
|
function CacheListener() { }
|
|
CacheListener.prototype = {
|
|
_appCache: null,
|
|
|
|
QueryInterface(iid) {
|
|
if (iid.equals(Components.interfaces.nsICacheEntryOpenCallback) ||
|
|
iid.equals(Components.interfaces.nsISupports))
|
|
return this;
|
|
throw Components.results.NS_ERROR_NO_INTERFACE;
|
|
},
|
|
|
|
onCacheEntryCheck(entry, appCache) {
|
|
return Ci.nsICacheEntryOpenCallback.ENTRY_WANTED;
|
|
},
|
|
|
|
onCacheEntryAvailable(entry, isnew, appCache, status) {
|
|
resolve();
|
|
},
|
|
|
|
run() {
|
|
let storage = getCacheStorage(where, lci, this._appCache);
|
|
storage.asyncOpenURI(key, "", flags, this);
|
|
}
|
|
};
|
|
|
|
(new CacheListener()).run();
|
|
});
|
|
}
|
|
|
|
//
|
|
// Test functions.
|
|
//
|
|
|
|
// Cookies
|
|
async function test_cookie_cleared() {
|
|
let tabs = [];
|
|
|
|
for (let userContextId of Object.keys(USER_CONTEXTS)) {
|
|
// Load the page in 2 different contexts and set a cookie
|
|
// which should only be visible in that context.
|
|
let value = USER_CONTEXTS[userContextId];
|
|
|
|
// Open our tab in the given user context.
|
|
tabs[userContextId] = await openTabInUserContext(TEST_URL + "file_reflect_cookie_into_title.html?" + value, userContextId);
|
|
|
|
// Close this tab.
|
|
await BrowserTestUtils.removeTab(tabs[userContextId].tab);
|
|
}
|
|
// Check that cookies have been set properly.
|
|
for (let userContextId of Object.keys(USER_CONTEXTS)) {
|
|
let enumerator = getCookiesForOA(TEST_HOST, userContextId);
|
|
ok(enumerator.hasMoreElements(), "Cookies available");
|
|
|
|
let foundCookie = enumerator.getNext().QueryInterface(Ci.nsICookie2);
|
|
Assert.equal(foundCookie["name"], COOKIE_NAME, "Check cookie name");
|
|
Assert.equal(foundCookie["value"], USER_CONTEXTS[userContextId], "Check cookie value");
|
|
}
|
|
|
|
// Forget the site.
|
|
await ForgetAboutSite.removeDataFromDomain(TEST_HOST);
|
|
|
|
// Check that whether cookies has been cleared or not.
|
|
for (let userContextId of Object.keys(USER_CONTEXTS)) {
|
|
let enumerator = getCookiesForOA(TEST_HOST, userContextId);
|
|
ok(!enumerator.hasMoreElements(), "No Cookie should be here");
|
|
}
|
|
}
|
|
|
|
// Cache
|
|
async function test_cache_cleared() {
|
|
// First, add some caches.
|
|
for (let userContextId of Object.keys(USER_CONTEXTS)) {
|
|
await OpenCacheEntry("http://" + TEST_HOST + "/",
|
|
"disk",
|
|
Ci.nsICacheStorage.OPEN_NORMALLY,
|
|
LoadContextInfo.custom(false, {userContextId}));
|
|
|
|
await OpenCacheEntry("http://" + TEST_HOST + "/",
|
|
"memory",
|
|
Ci.nsICacheStorage.OPEN_NORMALLY,
|
|
LoadContextInfo.custom(false, {userContextId}));
|
|
}
|
|
|
|
|
|
// Check that caches have been set correctly.
|
|
for (let userContextId of Object.keys(USER_CONTEXTS)) {
|
|
let mem = getCacheStorage("memory", LoadContextInfo.custom(false, {userContextId}));
|
|
let disk = getCacheStorage("disk", LoadContextInfo.custom(false, {userContextId}));
|
|
|
|
Assert.ok(mem.exists(createURI("http://" + TEST_HOST + "/"), ""), "The memory cache has been set correctly");
|
|
Assert.ok(disk.exists(createURI("http://" + TEST_HOST + "/"), ""), "The disk cache has been set correctly");
|
|
}
|
|
|
|
// Forget the site.
|
|
await ForgetAboutSite.removeDataFromDomain(TEST_HOST);
|
|
|
|
// Check that do caches be removed or not?
|
|
for (let userContextId of Object.keys(USER_CONTEXTS)) {
|
|
let mem = getCacheStorage("memory", LoadContextInfo.custom(false, {userContextId}));
|
|
let disk = getCacheStorage("disk", LoadContextInfo.custom(false, {userContextId}));
|
|
|
|
Assert.ok(!mem.exists(createURI("http://" + TEST_HOST + "/"), ""), "The memory cache is cleared");
|
|
Assert.ok(!disk.exists(createURI("http://" + TEST_HOST + "/"), ""), "The disk cache is cleared");
|
|
}
|
|
}
|
|
|
|
// Image Cache
|
|
async function test_image_cache_cleared() {
|
|
let tabs = [];
|
|
|
|
for (let userContextId of Object.keys(USER_CONTEXTS)) {
|
|
// Open our tab in the given user context to cache image.
|
|
tabs[userContextId] = await openTabInUserContext("http://localhost:" + gHttpServer.identity.primaryPort + "/loadImage.html",
|
|
userContextId);
|
|
await BrowserTestUtils.removeTab(tabs[userContextId].tab);
|
|
}
|
|
|
|
let expectedHits = USER_CONTEXTS.length;
|
|
|
|
// Check that image cache works with the userContextId.
|
|
is(gHits, expectedHits, "The image should be loaded" + expectedHits + "times.");
|
|
|
|
// Reset the cache count.
|
|
gHits = 0;
|
|
|
|
// Forget the site.
|
|
await ForgetAboutSite.removeDataFromDomain("localhost:" + gHttpServer.identity.primaryPort + "/");
|
|
|
|
// Load again.
|
|
for (let userContextId of Object.keys(USER_CONTEXTS)) {
|
|
// Open our tab in the given user context to cache image.
|
|
tabs[userContextId] = await openTabInUserContext("http://localhost:" + gHttpServer.identity.primaryPort + "/loadImage.html",
|
|
userContextId);
|
|
await BrowserTestUtils.removeTab(tabs[userContextId].tab);
|
|
}
|
|
|
|
// Check that image cache was cleared and the server gets another two hits.
|
|
is(gHits, expectedHits, "The image should be loaded" + expectedHits + "times.");
|
|
}
|
|
|
|
// Offline Storage
|
|
async function test_storage_cleared() {
|
|
for (let userContextId of Object.keys(USER_CONTEXTS)) {
|
|
// Load the page in 2 different contexts and set the local storage
|
|
// which should only be visible in that context.
|
|
let value = USER_CONTEXTS[userContextId];
|
|
|
|
// Open our tab in the given user context.
|
|
let tabInfo = await openTabInUserContext(TEST_URL + "file_set_storages.html?" + value, userContextId);
|
|
|
|
// Check that the storages has been set correctly.
|
|
await ContentTask.spawn(tabInfo.browser, { userContext: USER_CONTEXTS[userContextId] }, async function(arg) {
|
|
// Check that the local storage has been set correctly.
|
|
Assert.equal(content.localStorage.getItem("userContext"), arg.userContext, "Check the local storage value");
|
|
|
|
// Check that the session storage has been set correctly.
|
|
Assert.equal(content.sessionStorage.getItem("userContext"), arg.userContext, "Check the session storage value");
|
|
|
|
// Check that the indexedDB has been set correctly.
|
|
let request = content.indexedDB.open("idb", 1);
|
|
|
|
let db = await new Promise(done => {
|
|
request.onsuccess = event => {
|
|
done(event.target.result);
|
|
};
|
|
});
|
|
|
|
let transaction = db.transaction(["obj"], "readonly");
|
|
let store = transaction.objectStore("obj");
|
|
let storeRequest = store.get(1);
|
|
|
|
await new Promise(done => {
|
|
storeRequest.onsuccess = event => {
|
|
let res = storeRequest.result;
|
|
Assert.equal(res.userContext, arg.userContext, "Check the indexedDB value");
|
|
done();
|
|
};
|
|
});
|
|
});
|
|
|
|
// Close this tab.
|
|
await BrowserTestUtils.removeTab(tabInfo.tab);
|
|
}
|
|
|
|
// Forget the site.
|
|
await ForgetAboutSite.removeDataFromDomain(TEST_HOST);
|
|
|
|
// Open the tab again without setting the localStorage and check that the
|
|
// local storage has been cleared or not.
|
|
for (let userContextId of Object.keys(USER_CONTEXTS)) {
|
|
// Open our tab in the given user context without setting local storage.
|
|
let tabInfo = await openTabInUserContext(TEST_URL + "file_set_storages.html", userContextId);
|
|
|
|
// Check that do storages be cleared or not.
|
|
await ContentTask.spawn(tabInfo.browser, null, async function() {
|
|
// Check that does the local storage be cleared or not.
|
|
Assert.ok(!content.localStorage.getItem("userContext"), "The local storage has been cleared");
|
|
|
|
// Check that does the session storage be cleared or not.
|
|
Assert.ok(!content.sessionStorage.getItem("userContext"), "The session storage has been cleared");
|
|
|
|
// Check that does the indexedDB be cleared or not.
|
|
let request = content.indexedDB.open("idb", 1);
|
|
|
|
let db = await new Promise(done => {
|
|
request.onsuccess = event => {
|
|
done(event.target.result);
|
|
};
|
|
});
|
|
try {
|
|
db.transaction(["obj"], "readonly");
|
|
Assert.ok(false, "The indexedDB should not exist");
|
|
} catch (e) {
|
|
Assert.equal(e.name, "NotFoundError", "The indexedDB does not exist as expected");
|
|
}
|
|
});
|
|
|
|
// Close the tab.
|
|
await BrowserTestUtils.removeTab(tabInfo.tab);
|
|
}
|
|
}
|
|
|
|
add_task(async function setup() {
|
|
// Make sure userContext is enabled.
|
|
await SpecialPowers.pushPrefEnv({"set": [
|
|
["privacy.userContext.enabled", true]
|
|
]});
|
|
|
|
// Create a http server for the image cache test.
|
|
if (!gHttpServer) {
|
|
gHttpServer = new HttpServer();
|
|
gHttpServer.registerPathHandler("/image.png", imageHandler);
|
|
gHttpServer.registerPathHandler("/loadImage.html", loadImagePageHandler);
|
|
gHttpServer.start(-1);
|
|
}
|
|
});
|
|
|
|
let tests = [
|
|
test_cookie_cleared,
|
|
test_cache_cleared,
|
|
test_image_cache_cleared,
|
|
test_storage_cleared,
|
|
];
|
|
|
|
add_task(async function test() {
|
|
for (let i = 0; i < tests.length; i++)
|
|
add_task(tests[i]);
|
|
});
|
|
|
|
registerCleanupFunction(() => {
|
|
gHttpServer.stop(() => {
|
|
gHttpServer = null;
|
|
});
|
|
});
|