forked from mirrors/gecko-dev
257 lines
8.8 KiB
JavaScript
257 lines
8.8 KiB
JavaScript
/**
|
|
* Bug 1277803 - A test caes for testing favicon loading across different userContextId.
|
|
*/
|
|
|
|
const { classes: Cc, Constructor: CC, interfaces: Ci, utils: Cu } = Components;
|
|
|
|
XPCOMUtils.defineLazyModuleGetter(this, "Promise",
|
|
"resource://gre/modules/Promise.jsm");
|
|
|
|
const TEST_SITE = "http://example.net";
|
|
const TEST_THIRD_PARTY_SITE = "http://mochi.test:8888";
|
|
|
|
const TEST_PAGE = TEST_SITE + "/browser/browser/components/originattributes/" +
|
|
"test/browser/file_favicon.html";
|
|
const FAVICON_URI = TEST_SITE + "/browser/browser/components/originattributes/" +
|
|
"test/browser/file_favicon.png";
|
|
const TEST_THIRD_PARTY_PAGE = "http://example.com/browser/browser/components/" +
|
|
"originattributes/test/browser/file_favicon_thirdParty.html";
|
|
const THIRD_PARTY_FAVICON_URI = TEST_THIRD_PARTY_SITE + "/browser/browser/components/" +
|
|
"originattributes/test/browser/file_favicon.png";
|
|
|
|
const USER_CONTEXT_ID_PERSONAL = 1;
|
|
const USER_CONTEXT_ID_WORK = 2;
|
|
|
|
let systemPrincipal = Services.scriptSecurityManager.getSystemPrincipal();
|
|
let makeURI = Cu.import("resource://gre/modules/BrowserUtils.jsm", {}).BrowserUtils.makeURI;
|
|
|
|
function clearAllImageCaches() {
|
|
var tools = SpecialPowers.Cc["@mozilla.org/image/tools;1"]
|
|
.getService(SpecialPowers.Ci.imgITools);
|
|
var imageCache = tools.getImgCacheForDocument(window.document);
|
|
imageCache.clearCache(true); // true=chrome
|
|
imageCache.clearCache(false); // false=content
|
|
}
|
|
|
|
function clearAllPlacesFavicons() {
|
|
let faviconService = Cc["@mozilla.org/browser/favicon-service;1"]
|
|
.getService(Ci.nsIFaviconService);
|
|
|
|
return new Promise(resolve => {
|
|
let observer = {
|
|
observe(aSubject, aTopic, aData) {
|
|
if (aTopic === "places-favicons-expired") {
|
|
resolve();
|
|
Services.obs.removeObserver(observer, "places-favicons-expired");
|
|
}
|
|
}
|
|
};
|
|
|
|
Services.obs.addObserver(observer, "places-favicons-expired", false);
|
|
faviconService.expireAllFavicons();
|
|
});
|
|
}
|
|
|
|
function FaviconObserver(aUserContextId, aExpectedCookie, aPageURI, aFaviconURL) {
|
|
this.reset(aUserContextId, aExpectedCookie, aPageURI, aFaviconURL);
|
|
}
|
|
|
|
FaviconObserver.prototype = {
|
|
observe(aSubject, aTopic, aData) {
|
|
// Make sure that the topic is 'http-on-modify-request'.
|
|
if (aTopic === "http-on-modify-request") {
|
|
// We check the userContextId for the originAttributes of the loading
|
|
// channel. All requests for the favicon should contain the correct
|
|
// userContextId. There are two requests for a favicon loading, one
|
|
// from the Places library and one from the XUL image. The difference
|
|
// of them is the loading principal. The Places will use the content
|
|
// principal and the XUL image will use the system principal.
|
|
|
|
let httpChannel = aSubject.QueryInterface(Ci.nsIHttpChannel);
|
|
let reqLoadInfo = httpChannel.loadInfo;
|
|
let loadingPrincipal;
|
|
let triggeringPrincipal;
|
|
|
|
// Make sure this is a favicon request.
|
|
if (httpChannel.URI.spec !== this._faviconURL) {
|
|
return;
|
|
}
|
|
|
|
if (reqLoadInfo) {
|
|
loadingPrincipal = reqLoadInfo.loadingPrincipal;
|
|
triggeringPrincipal = reqLoadInfo.triggeringPrincipal;
|
|
}
|
|
|
|
// Check the userContextId.
|
|
is(reqLoadInfo.originAttributes.userContextId, this._curUserContextId,
|
|
"The loadInfo has correct userContextId");
|
|
|
|
if (loadingPrincipal.equals(systemPrincipal)) {
|
|
this._faviconReqXUL = true;
|
|
ok(triggeringPrincipal.equals(this._expectedPrincipal),
|
|
"The triggeringPrincipal of favicon loading from XUL should be the content principal.");
|
|
} else {
|
|
this._faviconReqPlaces = true;
|
|
ok(loadingPrincipal.equals(this._expectedPrincipal),
|
|
"The loadingPrincipal of favicon loading from Places should be the content prinicpal");
|
|
}
|
|
|
|
let faviconCookie = httpChannel.getRequestHeader("cookie");
|
|
|
|
is(faviconCookie, this._expectedCookie, "The cookie of the favicon loading is correct.");
|
|
} else {
|
|
ok(false, "Received unexpected topic: ", aTopic);
|
|
}
|
|
|
|
if (this._faviconReqXUL && this._faviconReqPlaces) {
|
|
this._faviconLoaded.resolve();
|
|
}
|
|
},
|
|
|
|
reset(aUserContextId, aExpectedCookie, aPageURI, aFaviconURL) {
|
|
this._curUserContextId = aUserContextId;
|
|
this._expectedCookie = aExpectedCookie;
|
|
this._expectedPrincipal = Services.scriptSecurityManager
|
|
.createCodebasePrincipal(aPageURI, { userContextId: aUserContextId });
|
|
this._faviconReqXUL = false;
|
|
this._faviconReqPlaces = false;
|
|
this._faviconURL = aFaviconURL;
|
|
this._faviconLoaded = new Promise.defer();
|
|
},
|
|
|
|
get promise() {
|
|
return this._faviconLoaded.promise;
|
|
}
|
|
};
|
|
|
|
function waitOnFaviconLoaded(aFaviconURL) {
|
|
return new Promise(resolve => {
|
|
let observer = {
|
|
onPageChanged(uri, attr, value, id) {
|
|
|
|
if (attr === Ci.nsINavHistoryObserver.ATTRIBUTE_FAVICON &&
|
|
value === aFaviconURL) {
|
|
resolve();
|
|
PlacesUtils.history.removeObserver(observer, false);
|
|
}
|
|
},
|
|
};
|
|
|
|
PlacesUtils.history.addObserver(observer, false);
|
|
});
|
|
}
|
|
|
|
function* generateCookies(aHost) {
|
|
// we generate two different cookies for two userContextIds.
|
|
let cookies = [];
|
|
cookies.push(Math.random().toString());
|
|
cookies.push(Math.random().toString());
|
|
|
|
// Then, we add cookies into the site for 'personal' and 'work'.
|
|
let tabInfoA = yield openTabInUserContext(aHost, USER_CONTEXT_ID_PERSONAL);
|
|
let tabInfoB = yield openTabInUserContext(aHost, USER_CONTEXT_ID_WORK);
|
|
|
|
yield ContentTask.spawn(tabInfoA.browser, cookies[0], function* (value) {
|
|
content.document.cookie = value;
|
|
});
|
|
|
|
yield ContentTask.spawn(tabInfoB.browser, cookies[1], function* (value) {
|
|
content.document.cookie = value;
|
|
});
|
|
|
|
yield BrowserTestUtils.removeTab(tabInfoA.tab);
|
|
yield BrowserTestUtils.removeTab(tabInfoB.tab);
|
|
|
|
return cookies;
|
|
}
|
|
|
|
function* doTest(aTestPage, aFaviconHost, aFaviconURL) {
|
|
let cookies = yield generateCookies(aFaviconHost);
|
|
let pageURI = makeURI(aTestPage);
|
|
|
|
// Create the observer object for observing request channels of the personal
|
|
// container.
|
|
let observer = new FaviconObserver(USER_CONTEXT_ID_PERSONAL, cookies[0], pageURI, aFaviconURL);
|
|
|
|
// Add the observer earlier in case we miss it.
|
|
let promiseWaitOnFaviconLoaded = waitOnFaviconLoaded(aFaviconURL);
|
|
|
|
Services.obs.addObserver(observer, "http-on-modify-request", false);
|
|
|
|
// Open the tab with the personal container.
|
|
let tabInfo = yield openTabInUserContext(aTestPage, USER_CONTEXT_ID_PERSONAL);
|
|
|
|
// Waiting for favicon requests are all made.
|
|
yield observer.promise;
|
|
// Waiting for favicon loaded.
|
|
yield promiseWaitOnFaviconLoaded;
|
|
|
|
// Close the tab.
|
|
yield BrowserTestUtils.removeTab(tabInfo.tab);
|
|
|
|
// Reset the observer for observing requests for the work container.
|
|
observer.reset(USER_CONTEXT_ID_WORK, cookies[1], pageURI, aFaviconURL);
|
|
tabInfo = yield openTabInUserContext(aTestPage, USER_CONTEXT_ID_WORK);
|
|
|
|
// Waiting for favicon requests are all made.
|
|
yield observer.promise;
|
|
|
|
Services.obs.removeObserver(observer, "http-on-modify-request");
|
|
|
|
yield BrowserTestUtils.removeTab(tabInfo.tab);
|
|
}
|
|
|
|
add_task(function* setup() {
|
|
// Make sure userContext is enabled.
|
|
yield SpecialPowers.pushPrefEnv({"set": [
|
|
["privacy.userContext.enabled", true]
|
|
]});
|
|
});
|
|
|
|
// A clean up function to prevent affecting other tests.
|
|
registerCleanupFunction(() => {
|
|
// Clear all cookies.
|
|
let cookieMgr = Cc["@mozilla.org/cookiemanager;1"]
|
|
.getService(Ci.nsICookieManager);
|
|
cookieMgr.removeAll();
|
|
|
|
// Clear all image caches and network caches.
|
|
clearAllImageCaches();
|
|
|
|
let networkCache = Cc["@mozilla.org/netwerk/cache-storage-service;1"]
|
|
.getService(Ci.nsICacheStorageService);
|
|
networkCache.clear();
|
|
|
|
// Clear Places favicon caches.
|
|
clearAllPlacesFavicons();
|
|
});
|
|
|
|
add_task(function* test_favicon_userContextId() {
|
|
// Clear all image caches before running the test.
|
|
clearAllImageCaches();
|
|
|
|
// Clear all network caches.
|
|
let networkCache = Cc["@mozilla.org/netwerk/cache-storage-service;1"]
|
|
.getService(Ci.nsICacheStorageService);
|
|
networkCache.clear();
|
|
|
|
// Clear Places favicon caches.
|
|
yield clearAllPlacesFavicons();
|
|
|
|
yield doTest(TEST_PAGE, TEST_SITE, FAVICON_URI);
|
|
});
|
|
|
|
add_task(function* test_thirdPartyFavicon_userContextId() {
|
|
// Clear all image caches before running the test.
|
|
clearAllImageCaches();
|
|
|
|
// Clear all network caches.
|
|
let networkCache = Cc["@mozilla.org/netwerk/cache-storage-service;1"]
|
|
.getService(Ci.nsICacheStorageService);
|
|
networkCache.clear();
|
|
|
|
// Clear Places favicon caches.
|
|
yield clearAllPlacesFavicons();
|
|
|
|
yield doTest(TEST_THIRD_PARTY_PAGE, TEST_THIRD_PARTY_SITE, THIRD_PARTY_FAVICON_URI);
|
|
});
|