Backed out 3 changesets (bug 1523272) for Browser-chrome and tv failures in browser/components/preferences/in-content/tests/siteData/browser_siteData3.js

Backed out changeset ddf39b3e96df (bug 1523272)
Backed out changeset 8fbf00832008 (bug 1523272)
Backed out changeset 7250b9f956b6 (bug 1523272)
This commit is contained in:
Dorel Luca 2019-02-07 13:55:33 +02:00
Родитель 3a0fff40b3
Коммит 28f51339d1
9 изменённых файлов: 363 добавлений и 407 удалений

Просмотреть файл

@ -15,8 +15,6 @@ XPCOMUtils.defineLazyServiceGetter(this, "swm",
"@mozilla.org/serviceworkers/manager;1",
"nsIServiceWorkerManager");
XPCOMUtils.defineLazyGlobalGetters(this, ["indexedDB", "Blob"]);
/**
* This module assists with tasks around testing functionality that shows
* or clears site data.
@ -27,44 +25,31 @@ XPCOMUtils.defineLazyGlobalGetters(this, ["indexedDB", "Blob"]);
var SiteDataTestUtils = {
/**
* Makes an origin have persistent data storage.
*
* @param {String} origin - the origin of the site to give persistent storage
*
* @returns a Promise that resolves when storage was persisted
*/
persist(origin, value = Services.perms.ALLOW_ACTION) {
return new Promise(resolve => {
let principal = Services.scriptSecurityManager.createCodebasePrincipalFromOrigin(origin);
Services.perms.addFromPrincipal(principal, "persistent-storage", value);
Services.qms.persist(principal).callback = () => resolve();
});
},
/**
* Adds a new blob entry to a dummy indexedDB database for the specified origin.
* Adds a new entry to a dummy indexedDB database for the specified origin.
*
* @param {String} origin - the origin of the site to add test data for
* @param {Number} size [optional] - the size of the entry in bytes
* @param {String} name [optional] - the entry key
* @param {String} value [optional] - the entry value
* @param {Object} originAttributes [optional] - the originAttributes
*
* @returns a Promise that resolves when the data was added successfully.
*/
addToIndexedDB(origin, size = 1024) {
addToIndexedDB(origin, key = "foo", value = "bar", originAttributes = {}) {
return new Promise(resolve => {
let principal = Services.scriptSecurityManager.createCodebasePrincipalFromOrigin(origin);
let uri = Services.io.newURI(origin);
let principal =
Services.scriptSecurityManager.createCodebasePrincipal(uri, originAttributes);
let request = indexedDB.openForPrincipal(principal, "TestDatabase", 1);
request.onupgradeneeded = function(e) {
let db = e.target.result;
db.createObjectStore("TestStore");
db.createObjectStore("TestStore", { keyPath: "id" });
};
request.onsuccess = function(e) {
let db = e.target.result;
let tx = db.transaction("TestStore", "readwrite");
let store = tx.objectStore("TestStore");
tx.oncomplete = resolve;
let buffer = new ArrayBuffer(size);
let blob = new Blob([buffer]);
store.add(blob, Cu.now());
store.put({ id: key, description: value});
};
});
},
@ -78,8 +63,8 @@ var SiteDataTestUtils = {
* @param {String} value [optional] - the cookie value
*/
addToCookies(origin, name = "foo", value = "bar") {
let principal = Services.scriptSecurityManager.createCodebasePrincipalFromOrigin(origin);
Services.cookies.add(principal.URI.host, principal.URI.pathQueryRef, name, value,
let uri = Services.io.newURI(origin);
Services.cookies.add(uri.host, uri.pathQueryRef, name, value,
false, false, false, Date.now() + 24000 * 60 * 60, {},
Ci.nsICookie2.SAMESITE_UNSET);
},
@ -136,7 +121,8 @@ var SiteDataTestUtils = {
*/
getQuotaUsage(origin) {
return new Promise(resolve => {
let principal = Services.scriptSecurityManager.createCodebasePrincipalFromOrigin(origin);
let uri = Services.io.newURI(origin);
let principal = Services.scriptSecurityManager.createCodebasePrincipal(uri, {});
Services.qms.getUsageForPrincipal(principal, request => resolve(request.result.usage));
});
},

Просмотреть файл

@ -18,9 +18,8 @@ function checkDataForAboutURL() {
}
function createIndexedDB(host, originAttributes) {
let uri = Services.io.newURI("https://" + host);
let principal = Services.scriptSecurityManager.createCodebasePrincipal(uri, originAttributes);
return SiteDataTestUtils.addToIndexedDB(principal.origin);
return SiteDataTestUtils.addToIndexedDB("https://" + host, "foo", "bar",
originAttributes);
}
function checkIndexedDB(host, originAttributes) {

Просмотреть файл

@ -12,8 +12,8 @@ function assertAllSitesNotListed(win) {
}
// Test selecting and removing all sites one by one
add_task(async function test_selectRemove() {
let hosts = await addTestData([
add_task(async function() {
mockSiteDataManager.register(SiteDataManager, [
{
usage: 1024,
origin: "https://account.xyz.com",
@ -22,6 +22,7 @@ add_task(async function test_selectRemove() {
{
usage: 1024,
origin: "https://shopping.xyz.com",
persisted: false,
},
{
usage: 1024,
@ -31,11 +32,12 @@ add_task(async function test_selectRemove() {
{
usage: 1024,
origin: "http://email.bar.com",
persisted: false,
},
]);
let fakeHosts = mockSiteDataManager.fakeSites.map(site => site.principal.URI.host);
let updatePromise = promiseSiteDataManagerSitesUpdated();
await openPreferencesViaOpenPreferencesAPI("privacy", { leaveOpen: true });
await updatePromise;
await openSiteDataSettingsDialog();
@ -48,7 +50,7 @@ add_task(async function test_selectRemove() {
let settingsDialogClosePromise = null;
// Test the initial state
assertSitesListed(doc, hosts);
assertSitesListed(doc, fakeHosts);
// Test the "Cancel" button
settingsDialogClosePromise = promiseSettingsDialogClose();
@ -59,7 +61,7 @@ add_task(async function test_selectRemove() {
cancelBtn.doCommand();
await settingsDialogClosePromise;
await openSiteDataSettingsDialog();
assertSitesListed(doc, hosts);
assertSitesListed(doc, fakeHosts);
// Test the "Save Changes" button but cancelling save
let cancelPromise = BrowserTestUtils.promiseAlertDialogOpen("cancel");
@ -74,7 +76,7 @@ add_task(async function test_selectRemove() {
cancelBtn.doCommand();
await settingsDialogClosePromise;
await openSiteDataSettingsDialog();
assertSitesListed(doc, hosts);
assertSitesListed(doc, fakeHosts);
// Test the "Save Changes" button and accepting save
let acceptPromise = BrowserTestUtils.promiseAlertDialogOpen("accept");
@ -91,7 +93,7 @@ add_task(async function test_selectRemove() {
await openSiteDataSettingsDialog();
assertAllSitesNotListed(win);
await SiteDataTestUtils.clear();
await mockSiteDataManager.unregister();
BrowserTestUtils.removeTab(gBrowser.selectedTab);
function removeAllSitesOneByOne() {
@ -107,8 +109,8 @@ add_task(async function test_selectRemove() {
});
// Test selecting and removing partial sites
add_task(async function test_removePartialSites() {
let hosts = await addTestData([
add_task(async function() {
mockSiteDataManager.register(SiteDataManager, [
{
usage: 1024,
origin: "https://account.xyz.com",
@ -139,10 +141,15 @@ add_task(async function test_removePartialSites() {
origin: "https://127.0.0.1",
persisted: false,
},
{
usage: 1024,
origin: "https://[0:0:0:0:0:0:0:1]",
persisted: true,
},
]);
let fakeHosts = mockSiteDataManager.fakeSites.map(site => site.principal.URI.host);
let updatePromise = promiseSiteDataManagerSitesUpdated();
await openPreferencesViaOpenPreferencesAPI("privacy", { leaveOpen: true });
await updatePromise;
await openSiteDataSettingsDialog();
@ -156,18 +163,18 @@ add_task(async function test_removePartialSites() {
let settingsDialogClosePromise = null;
// Test the initial state
assertSitesListed(doc, hosts);
assertSitesListed(doc, fakeHosts);
// Test the "Cancel" button
settingsDialogClosePromise = promiseSettingsDialogClose();
frameDoc = win.gSubDialog._topDialog._frame.contentDocument;
cancelBtn = frameDoc.getElementById("cancel");
await removeSelectedSite(hosts.slice(0, 2));
assertSitesListed(doc, hosts.slice(2));
removeSelectedSite(fakeHosts.slice(0, 2));
assertSitesListed(doc, fakeHosts.slice(2));
cancelBtn.doCommand();
await settingsDialogClosePromise;
await openSiteDataSettingsDialog();
assertSitesListed(doc, hosts);
assertSitesListed(doc, fakeHosts);
// Test the "Save Changes" button but canceling save
removeDialogOpenPromise = BrowserTestUtils.promiseAlertDialogOpen("cancel", REMOVE_DIALOG_URL);
@ -175,49 +182,44 @@ add_task(async function test_removePartialSites() {
frameDoc = win.gSubDialog._topDialog._frame.contentDocument;
saveBtn = frameDoc.getElementById("save");
cancelBtn = frameDoc.getElementById("cancel");
await removeSelectedSite(hosts.slice(0, 2));
assertSitesListed(doc, hosts.slice(2));
removeSelectedSite(fakeHosts.slice(0, 2));
assertSitesListed(doc, fakeHosts.slice(2));
saveBtn.doCommand();
await removeDialogOpenPromise;
cancelBtn.doCommand();
await settingsDialogClosePromise;
await openSiteDataSettingsDialog();
assertSitesListed(doc, hosts);
assertSitesListed(doc, fakeHosts);
// Test the "Save Changes" button and accepting save
removeDialogOpenPromise = BrowserTestUtils.promiseAlertDialogOpen("accept", REMOVE_DIALOG_URL);
settingsDialogClosePromise = promiseSettingsDialogClose();
frameDoc = win.gSubDialog._topDialog._frame.contentDocument;
saveBtn = frameDoc.getElementById("save");
await removeSelectedSite(hosts.slice(0, 2));
assertSitesListed(doc, hosts.slice(2));
removeSelectedSite(fakeHosts.slice(0, 2));
assertSitesListed(doc, fakeHosts.slice(2));
saveBtn.doCommand();
await removeDialogOpenPromise;
await settingsDialogClosePromise;
await openSiteDataSettingsDialog();
assertSitesListed(doc, hosts.slice(2));
assertSitesListed(doc, fakeHosts.slice(2));
await SiteDataTestUtils.clear();
await mockSiteDataManager.unregister();
BrowserTestUtils.removeTab(gBrowser.selectedTab);
function removeSelectedSite(removeHosts) {
function removeSelectedSite(hosts) {
frameDoc = win.gSubDialog._topDialog._frame.contentDocument;
let removeBtn = frameDoc.getElementById("removeSelected");
is(removeBtn.disabled, true, "Should start with disabled removeSelected button");
let sitesList = frameDoc.getElementById("sitesList");
removeHosts.forEach(host => {
hosts.forEach(host => {
let site = sitesList.querySelector(`richlistitem[host="${host}"]`);
if (site) {
site.click();
let currentSelectedIndex = sitesList.selectedIndex;
is(removeBtn.disabled, false, "Should enable the removeSelected button");
removeBtn.doCommand();
let newSelectedIndex = sitesList.selectedIndex;
if (currentSelectedIndex >= sitesList.itemCount) {
is(newSelectedIndex, currentSelectedIndex - 1);
} else {
is(newSelectedIndex, currentSelectedIndex);
}
is(sitesList.selectedIndex, currentSelectedIndex);
} else {
ok(false, `Should not select and remove inexistent site of ${host}`);
}
@ -227,7 +229,7 @@ add_task(async function test_removePartialSites() {
// Test searching and then removing only visible sites
add_task(async function() {
let hosts = await addTestData([
mockSiteDataManager.register(SiteDataManager, [
{
usage: 1024,
origin: "https://account.xyz.com",
@ -249,9 +251,9 @@ add_task(async function() {
persisted: false,
},
]);
let fakeHosts = mockSiteDataManager.fakeSites.map(site => site.principal.URI.host);
let updatePromise = promiseSiteDataManagerSitesUpdated();
await openPreferencesViaOpenPreferencesAPI("privacy", { leaveOpen: true });
await updatePromise;
await openSiteDataSettingsDialog();
@ -263,7 +265,7 @@ add_task(async function() {
let searchBox = frameDoc.getElementById("searchBox");
searchBox.value = "xyz";
searchBox.doCommand();
assertSitesListed(doc, hosts.filter(host => host.includes("xyz")));
assertSitesListed(doc, fakeHosts.filter(host => host.includes("xyz")));
// Test only removing all visible sites listed
updatePromise = promiseSiteDataManagerSitesUpdated();
@ -277,15 +279,15 @@ add_task(async function() {
await settingsDialogClosePromise;
await updatePromise;
await openSiteDataSettingsDialog();
assertSitesListed(doc, hosts.filter(host => !host.includes("xyz")));
assertSitesListed(doc, fakeHosts.filter(host => !host.includes("xyz")));
await SiteDataTestUtils.clear();
await mockSiteDataManager.unregister();
BrowserTestUtils.removeTab(gBrowser.selectedTab);
});
// Test dynamically clearing all site data
add_task(async function() {
let hosts = await addTestData([
mockSiteDataManager.register(SiteDataManager, [
{
usage: 1024,
origin: "https://account.xyz.com",
@ -297,28 +299,28 @@ add_task(async function() {
persisted: false,
},
]);
let updatePromise = promiseSiteDataManagerSitesUpdated();
let fakeHosts = mockSiteDataManager.fakeSites.map(site => site.principal.URI.host);
// Test the initial state
let updatePromise = promiseSiteDataManagerSitesUpdated();
await openPreferencesViaOpenPreferencesAPI("privacy", { leaveOpen: true });
await updatePromise;
await openSiteDataSettingsDialog();
let doc = gBrowser.selectedBrowser.contentDocument;
assertSitesListed(doc, hosts);
assertSitesListed(doc, fakeHosts);
await addTestData([
{
usage: 1024,
origin: "http://cinema.bar.com",
persisted: true,
},
{
usage: 1024,
origin: "http://email.bar.com",
persisted: false,
},
]);
// Add more sites dynamically
mockSiteDataManager.fakeSites.push({
usage: 1024,
principal: Services.scriptSecurityManager
.createCodebasePrincipalFromOrigin("http://cinema.bar.com"),
persisted: true,
}, {
usage: 1024,
principal: Services.scriptSecurityManager
.createCodebasePrincipalFromOrigin("http://email.bar.com"),
persisted: false,
});
// Test clearing all site data dynamically
let win = gBrowser.selectedBrowser.contentWindow;
@ -336,6 +338,6 @@ add_task(async function() {
await openSiteDataSettingsDialog();
assertAllSitesNotListed(win);
await SiteDataTestUtils.clear();
await mockSiteDataManager.unregister();
BrowserTestUtils.removeTab(gBrowser.selectedTab);
});

Просмотреть файл

@ -1,8 +1,8 @@
"use strict";
// Test not displaying sites which store 0 byte and don't have persistent storage.
add_task(async function test_exclusions() {
let hosts = await addTestData([
add_task(async function() {
mockSiteDataManager.register(SiteDataManager, [
{
usage: 0,
origin: "https://account.xyz.com",
@ -30,22 +30,23 @@ add_task(async function test_exclusions() {
persisted: false,
},
]);
let fakeHosts = mockSiteDataManager.fakeSites.map(site => site.principal.URI.host);
let updatePromise = promiseSiteDataManagerSitesUpdated();
let doc = gBrowser.selectedBrowser.contentDocument;
await openPreferencesViaOpenPreferencesAPI("privacy", { leaveOpen: true });
await updatePromise;
await openSiteDataSettingsDialog();
assertSitesListed(doc, hosts.filter(host => host != "shopping.xyz.com"));
assertSitesListed(doc, fakeHosts.filter(host => host != "shopping.xyz.com"));
await SiteDataTestUtils.clear();
await mockSiteDataManager.unregister();
BrowserTestUtils.removeTab(gBrowser.selectedTab);
});
// Test grouping and listing sites across scheme, port and origin attributes by host
add_task(async function test_grouping() {
let quotaUsage = 7000000;
await addTestData([
add_task(async function() {
const quotaUsage = 1024;
mockSiteDataManager.register(SiteDataManager, [
{
usage: quotaUsage,
origin: "https://account.xyz.com^userContextId=1",
@ -90,61 +91,40 @@ add_task(async function test_grouping() {
is(columns[1].value, "5", "Should group cookies across scheme, port and origin attributes");
let [value, unit] = DownloadUtils.convertByteUnits(quotaUsage * 4);
let l10nAttributes = frameDoc.l10n.getAttributes(columns[2]);
is(l10nAttributes.id, "site-usage-persistent",
"Should show the site as persistent if one origin is persistent.");
// The shown quota can be slightly larger than the raw data we put in (though it should
// never be smaller), but that doesn't really matter to us since we only want to test that
// the site data dialog accumulates this into a single column.
ok(parseFloat(l10nAttributes.args.value) >= parseFloat(value),
"Should show the correct accumulated quota size.");
is(l10nAttributes.args.unit, unit, "Should show the correct quota size unit.");
let [value, unit] = DownloadUtils.convertByteUnits(quotaUsage * mockSiteDataManager.fakeSites.length);
Assert.deepEqual(frameDoc.l10n.getAttributes(columns[2]), {
id: "site-usage-persistent",
args: { value, unit },
}, "Should sum up usages across scheme, port, origin attributes and persistent status");
await SiteDataTestUtils.clear();
await mockSiteDataManager.unregister();
BrowserTestUtils.removeTab(gBrowser.selectedTab);
});
// Test sorting
add_task(async function test_sorting() {
let testData = [
add_task(async function() {
mockSiteDataManager.register(SiteDataManager, [
{
baseDomain: "xyz.com",
usage: 1024,
origin: "https://account.xyz.com",
cookies: 6,
persisted: true,
},
{
baseDomain: "foo.com",
usage: 1024 * 2,
origin: "https://books.foo.com",
cookies: 0,
persisted: false,
},
{
baseDomain: "bar.com",
usage: 1024 * 3,
origin: "http://cinema.bar.com",
cookies: 3,
persisted: true,
},
];
await addTestData(testData);
// Add a bunch of cookies with slight delay to enable testing
// by last storage access.
for (let site of testData) {
/* eslint-disable-next-line mozilla/no-arbitrary-setTimeout */
await new Promise(r => setTimeout(r, 1500));
SiteDataTestUtils.addToCookies(site.origin, Cu.now());
site.cookies += 1;
site.lastAccessed = Cu.now();
}
]);
let updatePromise = promiseSiteDataManagerSitesUpdated();
await openPreferencesViaOpenPreferencesAPI("privacy", { leaveOpen: true });
await updatePromise;
await openSiteDataSettingsDialog();
@ -155,50 +135,146 @@ add_task(async function test_sorting() {
let hostCol = frameDoc.getElementById("hostCol");
let usageCol = frameDoc.getElementById("usageCol");
let cookiesCol = frameDoc.getElementById("cookiesCol");
let lastAccessedCol = frameDoc.getElementById("lastAccessedCol");
let sitesList = frameDoc.getElementById("sitesList");
function getHostOrder() {
let siteItems = sitesList.getElementsByTagName("richlistitem");
return Array.from(siteItems).map(item => item.getAttribute("host"));
}
// Test default sorting by usage, descending.
Assert.deepEqual(getHostOrder(),
["cinema.bar.com", "books.foo.com", "account.xyz.com"], "Has sorted descending by usage");
// Test default sorting
assertSortByUsage("descending");
// Test sorting on the usage column
usageCol.click();
Assert.deepEqual(getHostOrder(),
["account.xyz.com", "books.foo.com", "cinema.bar.com"], "Has sorted ascending by usage");
assertSortByUsage("ascending");
usageCol.click();
Assert.deepEqual(getHostOrder(),
["cinema.bar.com", "books.foo.com", "account.xyz.com"], "Has sorted descending by usage");
assertSortByUsage("descending");
// Test sorting on the host column
hostCol.click();
Assert.deepEqual(getHostOrder(),
["cinema.bar.com", "books.foo.com", "account.xyz.com"], "Has sorted ascending by base domain");
assertSortByBaseDomain("ascending");
hostCol.click();
Assert.deepEqual(getHostOrder(),
["account.xyz.com", "books.foo.com", "cinema.bar.com"], "Has sorted descending by base domain");
assertSortByBaseDomain("descending");
// Test sorting on the cookies column
cookiesCol.click();
Assert.deepEqual(getHostOrder(),
["books.foo.com", "cinema.bar.com", "account.xyz.com"], "Has sorted ascending by cookies");
assertSortByCookies("ascending");
cookiesCol.click();
Assert.deepEqual(getHostOrder(),
["account.xyz.com", "cinema.bar.com", "books.foo.com"], "Has sorted descending by cookies");
assertSortByCookies("descending");
await mockSiteDataManager.unregister();
BrowserTestUtils.removeTab(gBrowser.selectedTab);
function assertSortByBaseDomain(order) {
let siteItems = sitesList.getElementsByTagName("richlistitem");
for (let i = 0; i < siteItems.length - 1; ++i) {
let aHost = siteItems[i].getAttribute("host");
let bHost = siteItems[i + 1].getAttribute("host");
let a = findSiteByHost(aHost);
let b = findSiteByHost(bHost);
let result = a.baseDomain.localeCompare(b.baseDomain);
if (order == "ascending") {
Assert.lessOrEqual(result, 0, "Should sort sites in the ascending order by host");
} else {
Assert.greaterOrEqual(result, 0, "Should sort sites in the descending order by host");
}
}
}
function assertSortByUsage(order) {
let siteItems = sitesList.getElementsByTagName("richlistitem");
for (let i = 0; i < siteItems.length - 1; ++i) {
let aHost = siteItems[i].getAttribute("host");
let bHost = siteItems[i + 1].getAttribute("host");
let a = findSiteByHost(aHost);
let b = findSiteByHost(bHost);
let result = a.usage - b.usage;
if (order == "ascending") {
Assert.lessOrEqual(result, 0, "Should sort sites in the ascending order by usage");
} else {
Assert.greaterOrEqual(result, 0, "Should sort sites in the descending order by usage");
}
}
}
function assertSortByCookies(order) {
let siteItems = sitesList.getElementsByTagName("richlistitem");
for (let i = 0; i < siteItems.length - 1; ++i) {
let aHost = siteItems[i].getAttribute("host");
let bHost = siteItems[i + 1].getAttribute("host");
let a = findSiteByHost(aHost);
let b = findSiteByHost(bHost);
let result = a.cookies.length - b.cookies.length;
if (order == "ascending") {
Assert.lessOrEqual(result, 0, "Should sort sites in the ascending order by number of cookies");
} else {
Assert.greaterOrEqual(result, 0, "Should sort sites in the descending order by number of cookies");
}
}
}
function findSiteByHost(host) {
return mockSiteDataManager.fakeSites.find(site => site.principal.URI.host == host);
}
});
// Test sorting based on access date (separate from cookies for simplicity,
// since cookies access date affects this as well, but we don't mock our cookies)
add_task(async function() {
mockSiteDataManager.register(SiteDataManager, [
{
usage: 1024,
origin: "https://account.xyz.com",
persisted: true,
lastAccessed: (Date.now() - 120 * 1000) * 1000,
},
{
usage: 1024 * 2,
origin: "https://books.foo.com",
persisted: false,
lastAccessed: (Date.now() - 240 * 1000) * 1000,
},
{
usage: 1024 * 3,
origin: "http://cinema.bar.com",
persisted: true,
lastAccessed: Date.now() * 1000,
},
]);
let updatePromise = promiseSiteDataManagerSitesUpdated();
await openPreferencesViaOpenPreferencesAPI("privacy", { leaveOpen: true });
await updatePromise;
await openSiteDataSettingsDialog();
let dialog = content.gSubDialog._topDialog;
let dialogFrame = dialog._frame;
let frameDoc = dialogFrame.contentDocument;
let lastAccessedCol = frameDoc.getElementById("lastAccessedCol");
let sitesList = frameDoc.getElementById("sitesList");
// Test sorting on the date column
lastAccessedCol.click();
await TestUtils.waitForCondition(() => getHostOrder().join(",") == ["account.xyz.com", "books.foo.com", "cinema.bar.com"].join(","),
"Has sorted ascending by date");
assertSortByDate("ascending");
lastAccessedCol.click();
await TestUtils.waitForCondition(() => getHostOrder().join(",") == ["cinema.bar.com", "books.foo.com", "account.xyz.com"].join(","),
"Has sorted descending by date");
assertSortByDate("descending");
await SiteDataTestUtils.clear();
await mockSiteDataManager.unregister();
BrowserTestUtils.removeTab(gBrowser.selectedTab);
function assertSortByDate(order) {
let siteItems = sitesList.getElementsByTagName("richlistitem");
for (let i = 0; i < siteItems.length - 1; ++i) {
let aHost = siteItems[i].getAttribute("host");
let bHost = siteItems[i + 1].getAttribute("host");
let a = findSiteByHost(aHost);
let b = findSiteByHost(bHost);
let result = a.lastAccessed - b.lastAccessed;
if (order == "ascending") {
Assert.lessOrEqual(result, 0, "Should sort sites in the ascending order by date");
} else {
Assert.greaterOrEqual(result, 0, "Should sort sites in the descending order date");
}
}
}
function findSiteByHost(host) {
return mockSiteDataManager.fakeSites.find(site => site.principal.URI.host == host);
}
});

Просмотреть файл

@ -2,40 +2,44 @@
// Test selecting and removing partial sites
add_task(async function() {
await SiteDataTestUtils.clear();
let hosts = await addTestData([
mockSiteDataManager.register(SiteDataManager, [
{
usage: 1024,
origin: "https://account.xyz.com",
persisted: true,
},
{
usage: 1024,
origin: "https://shopping.xyz.com",
persisted: false,
},
{
usage: 1024,
origin: "http://cinema.bar.com",
persisted: true,
},
{
usage: 1024,
origin: "http://email.bar.com",
persisted: false,
},
{
usage: 1024,
origin: "https://s3-us-west-2.amazonaws.com",
persisted: true,
},
{
usage: 1024,
origin: "https://127.0.0.1",
persisted: false,
},
{
usage: 1024 * 4,
origin: "http://cinema.bar.com",
usage: 1024,
origin: "https://[0:0:0:0:0:0:0:1]",
persisted: true,
},
{
usage: 1024 * 3,
origin: "http://email.bar.com",
persisted: false,
},
{
usage: 1024 * 2,
origin: "https://s3-us-west-2.amazonaws.com",
persisted: true,
},
{
usage: 1024 * 6,
origin: "https://account.xyz.com",
persisted: true,
},
{
usage: 1024 * 5,
origin: "https://shopping.xyz.com",
persisted: false,
},
]);
let fakeHosts = mockSiteDataManager.fakeSites.map(site => site.principal.URI.host);
let updatePromise = promiseSiteDataManagerSitesUpdated();
await openPreferencesViaOpenPreferencesAPI("privacy", { leaveOpen: true });
@ -45,21 +49,18 @@ add_task(async function() {
let doc = gBrowser.selectedBrowser.contentDocument;
// Test the initial state
assertSitesListed(doc, hosts);
assertSitesListed(doc, fakeHosts);
let win = gBrowser.selectedBrowser.contentWindow;
let frameDoc = win.gSubDialog._topDialog._frame.contentDocument;
let removeBtn = frameDoc.getElementById("removeSelected");
is(removeBtn.disabled, true, "Should start with disabled removeSelected button");
let hostCol = frameDoc.getElementById("hostCol");
hostCol.click();
let removeDialogOpenPromise = BrowserTestUtils.promiseAlertDialogOpen("accept", REMOVE_DIALOG_URL);
let settingsDialogClosePromise = promiseSettingsDialogClose();
// Select some sites to remove.
let sitesList = frameDoc.getElementById("sitesList");
hosts.slice(0, 2).forEach(host => {
fakeHosts.slice(0, 2).forEach(host => {
let site = sitesList.querySelector(`richlistitem[host="${host}"]`);
sitesList.addItemToSelection(site);
});
@ -67,10 +68,10 @@ add_task(async function() {
is(removeBtn.disabled, false, "Should enable the removeSelected button");
removeBtn.doCommand();
is(sitesList.selectedIndex, 0, "Should select next item");
assertSitesListed(doc, hosts.slice(2));
assertSitesListed(doc, fakeHosts.slice(2));
// Select some other sites to remove with Delete.
hosts.slice(2, 4).forEach(host => {
fakeHosts.slice(2, 4).forEach(host => {
let site = sitesList.querySelector(`richlistitem[host="${host}"]`);
sitesList.addItemToSelection(site);
});
@ -78,21 +79,17 @@ add_task(async function() {
is(removeBtn.disabled, false, "Should enable the removeSelected button");
EventUtils.synthesizeKey("VK_DELETE");
is(sitesList.selectedIndex, 0, "Should select next item");
assertSitesListed(doc, hosts.slice(4));
assertSitesListed(doc, fakeHosts.slice(4));
updatePromise = promiseSiteDataManagerSitesUpdated();
let saveBtn = frameDoc.getElementById("save");
saveBtn.doCommand();
await removeDialogOpenPromise;
await settingsDialogClosePromise;
await updatePromise;
await openSiteDataSettingsDialog();
assertSitesListed(doc, hosts.slice(4));
assertSitesListed(doc, fakeHosts.slice(4));
await SiteDataTestUtils.clear();
await mockSiteDataManager.unregister();
BrowserTestUtils.removeTab(gBrowser.selectedTab);
});

Просмотреть файл

@ -127,29 +127,66 @@ function assertSitesListed(doc, hosts) {
is(removeAllBtn.disabled, false, "Should enable the removeAllBtn button");
}
async function addTestData(data) {
let hosts = [];
const mockSiteDataManager = {
for (let site of data) {
is(typeof site.origin, "string", "Passed an origin string into addTestData.");
if (site.persisted) {
await SiteDataTestUtils.persist(site.origin);
_SiteDataManager: null,
_originalQMS: null,
_originalRemoveQuotaUsage: null,
getUsage(onUsageResult) {
let result = this.fakeSites.map(site => ({
origin: site.principal.origin,
usage: site.usage,
persisted: site.persisted,
lastAccessed: site.lastAccessed,
}));
onUsageResult({ result, resultCode: Cr.NS_OK });
},
_removeQuotaUsage(site) {
var target = site.principals[0].URI.host;
this.fakeSites = this.fakeSites.filter(fakeSite => {
return fakeSite.principal.URI.host != target;
});
},
register(siteDataManager, fakeSites) {
this._SiteDataManager = siteDataManager;
this._originalQMS = this._SiteDataManager._qms;
this._SiteDataManager._qms = this;
this._originalRemoveQuotaUsage = this._SiteDataManager._removeQuotaUsage;
this._SiteDataManager._removeQuotaUsage = this._removeQuotaUsage.bind(this);
// Add some fake data.
this.fakeSites = fakeSites;
for (let site of fakeSites) {
if (!site.principal) {
site.principal = Services.scriptSecurityManager
.createCodebasePrincipalFromOrigin(site.origin);
}
let uri = site.principal.URI;
try {
site.baseDomain = Services.eTLD.getBaseDomainFromHost(uri.host);
} catch (e) {
site.baseDomain = uri.host;
}
// Add some cookies if needed.
for (let i = 0; i < (site.cookies || 0); i++) {
Services.cookies.add(uri.host, uri.pathQueryRef, Cu.now(), i,
false, false, false, Date.now() + 1000 * 60 * 60, {},
Ci.nsICookie2.SAMESITE_UNSET);
}
}
},
if (site.usage) {
await SiteDataTestUtils.addToIndexedDB(site.origin, site.usage);
}
for (let i = 0; i < (site.cookies || 0); i++) {
SiteDataTestUtils.addToCookies(site.origin, Cu.now());
}
let principal = Services.scriptSecurityManager.createCodebasePrincipalFromOrigin(site.origin);
hosts.push(principal.URI.host);
}
return hosts;
}
async unregister() {
await this._SiteDataManager.removeAll();
this.fakeSites = null;
this._SiteDataManager._qms = this._originalQMS;
this._SiteDataManager._removeQuotaUsage = this._originalRemoveQuotaUsage;
},
};
function promiseCookiesCleared() {
return TestUtils.topicObserved("cookie-changed", (subj, data) => {

Просмотреть файл

@ -3,6 +3,11 @@
const {XPCOMUtils} = ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
ChromeUtils.defineModuleGetter(this, "OfflineAppCacheHelper",
"resource://gre/modules/offlineAppCache.jsm");
ChromeUtils.defineModuleGetter(this, "ServiceWorkerCleanUp",
"resource://gre/modules/ServiceWorkerCleanUp.jsm");
var EXPORTED_SYMBOLS = [
"SiteDataManager",
];
@ -320,23 +325,6 @@ var SiteDataManager = {
site.cookies = [];
},
// Returns a list of permissions from the permission manager that
// we consider part of "site data and cookies".
_getDeletablePermissions() {
let perms = [];
let enumerator = Services.perms.enumerator;
while (enumerator.hasMoreElements()) {
let permission = enumerator.getNext().QueryInterface(Ci.nsIPermission);
if (permission.type == "persistent-storage" ||
permission.type == "storage-access") {
perms.push(permission);
}
}
return perms;
},
/**
* Removes all site data for the specified list of hosts.
*
@ -345,28 +333,35 @@ var SiteDataManager = {
* manager has been updated.
*/
async remove(hosts) {
let perms = this._getDeletablePermissions();
// Make sure we have up-to-date information.
await this._getQuotaUsage();
this._updateAppCache();
let unknownHost = "";
let promises = [];
for (let host of hosts) {
promises.push(new Promise(function(resolve) {
Services.clearData.deleteDataFromHost(host, true,
Ci.nsIClearDataService.CLEAR_COOKIES |
Ci.nsIClearDataService.CLEAR_DOM_STORAGES |
Ci.nsIClearDataService.CLEAR_SECURITY_SETTINGS |
Ci.nsIClearDataService.CLEAR_PLUGIN_DATA |
Ci.nsIClearDataService.CLEAR_EME |
Ci.nsIClearDataService.CLEAR_ALL_CACHES, resolve);
}));
for (let perm of perms) {
if (Services.eTLD.hasRootDomain(perm.principal.URI.host, host)) {
Services.perms.removePermission(perm);
}
let site = this._sites.get(host);
if (site) {
// Clear localStorage & sessionStorage
Services.obs.notifyObservers(null, "extension:purge-localStorage", host);
Services.obs.notifyObservers(null, "browser:purge-sessionStorage", host);
this._removePermission(site);
this._removeAppCache(site);
this._removeCookies(site);
promises.push(ServiceWorkerCleanUp.removeFromHost(host));
promises.push(this._removeQuotaUsage(site));
} else {
unknownHost = host;
break;
}
}
await Promise.all(promises);
if (unknownHost) {
throw `SiteDataManager: removing unknown site of ${unknownHost}`;
}
return this.updateSites();
},
@ -410,41 +405,54 @@ var SiteDataManager = {
* @returns a Promise that resolves when the data is cleared.
*/
async removeAll() {
await this.removeCache();
this.removeCache();
return this.removeSiteData();
},
/**
* Clears all caches.
*
* @returns a Promise that resolves when the data is cleared.
* Clears the entire network cache.
*/
removeCache() {
return new Promise(function(resolve) {
Services.clearData.deleteData(Ci.nsIClearDataService.CLEAR_ALL_CACHES, resolve);
});
Services.cache2.clear();
},
/**
* Clears all site data, but not cache, because the UI offers
* that functionality separately.
* Clears all site data, which currently means
* - Cookies
* - AppCache
* - LocalStorage
* - ServiceWorkers
* - Quota Managed Storage
* - persistent-storage permissions
*
* @returns a Promise that resolves when the data is cleared.
* @returns a Promise that resolves with the cache size on disk in bytes
*/
async removeSiteData() {
await new Promise(function(resolve) {
Services.clearData.deleteData(
Ci.nsIClearDataService.CLEAR_COOKIES |
Ci.nsIClearDataService.CLEAR_DOM_STORAGES |
Ci.nsIClearDataService.CLEAR_SECURITY_SETTINGS |
Ci.nsIClearDataService.CLEAR_EME |
Ci.nsIClearDataService.CLEAR_PLUGIN_DATA, resolve);
});
// LocalStorage
Services.obs.notifyObservers(null, "extension:purge-localStorage");
for (let permission of this._getDeletablePermissions()) {
Services.perms.removePermission(permission);
Services.cookies.removeAll();
OfflineAppCacheHelper.clear();
await ServiceWorkerCleanUp.removeAll();
// Refresh sites using quota usage again.
// This is for the case:
// 1. User goes to the about:preferences Site Data section.
// 2. With the about:preferences opened, user visits another website.
// 3. The website saves to quota usage, like indexedDB.
// 4. User goes back to the Site Data section and commands to clear all site data.
// For this case, we should refresh the site list so not to miss the website in the step 3.
// We don't do "Clear All" on the quota manager like the cookie, appcache, http cache above
// because that would clear browser data as well too,
// see https://bugzilla.mozilla.org/show_bug.cgi?id=1312361#c9
this._sites.clear();
await this._getQuotaUsage();
let promises = [];
for (let site of this._sites.values()) {
this._removePermission(site);
promises.push(this._removeQuotaUsage(site));
}
return this.updateSites();
return Promise.all(promises).then(() => this.updateSites());
},
};

Просмотреть файл

@ -1,148 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/
*/
"use strict";
const EXAMPLE_ORIGIN = "https://www.example.com";
const EXAMPLE_ORIGIN_2 = "https://example.org";
const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
const {SiteDataManager} = ChromeUtils.import("resource:///modules/SiteDataManager.jsm");
const {SiteDataTestUtils} = ChromeUtils.import("resource://testing-common/SiteDataTestUtils.jsm");
ChromeUtils.defineModuleGetter(this, "setTimeout", "resource://gre/modules/Timer.jsm");
ChromeUtils.defineModuleGetter(this, "TestUtils", "resource://testing-common/TestUtils.jsm");
add_task(function setup() {
do_get_profile();
});
add_task(async function testGetSites() {
SiteDataTestUtils.addToCookies(EXAMPLE_ORIGIN, "foo1", "bar1");
SiteDataTestUtils.addToCookies(EXAMPLE_ORIGIN, "foo2", "bar2");
await SiteDataTestUtils.addToIndexedDB(EXAMPLE_ORIGIN, 4096);
SiteDataTestUtils.addToCookies(EXAMPLE_ORIGIN_2, "foo", "bar");
await SiteDataTestUtils.addToIndexedDB(EXAMPLE_ORIGIN_2, 2048);
await SiteDataTestUtils.persist(EXAMPLE_ORIGIN_2);
await SiteDataManager.updateSites();
let sites = await SiteDataManager.getSites();
let site1 = sites.find((site) => site.baseDomain == "example.com");
let site2 = sites.find((site) => site.baseDomain == "example.org");
Assert.equal(site1.baseDomain, "example.com", "Has the correct base domain for example.com");
Assert.equal(site1.host, "www.example.com", "Has the correct host for example.com");
Assert.greater(site1.usage, 4096, "Has correct usage for example.com");
Assert.equal(site1.persisted, false, "example.com is not persisted");
Assert.equal(site1.cookies.length, 2, "Has correct number of cookies for example.com");
Assert.ok(typeof site1.lastAccessed.getDate == "function", "lastAccessed for example.com is a Date");
Assert.ok(site1.lastAccessed > Date.now() - 60 * 1000, "lastAccessed for example.com happened recently");
Assert.equal(site2.baseDomain, "example.org", "Has the correct base domain for example.org");
Assert.equal(site2.host, "example.org", "Has the correct host for example.org");
Assert.greater(site2.usage, 2048, "Has correct usage for example.org");
Assert.equal(site2.persisted, true, "example.org is persisted");
Assert.equal(site2.cookies.length, 1, "Has correct number of cookies for example.org");
Assert.ok(typeof site2.lastAccessed.getDate == "function", "lastAccessed for example.org is a Date");
Assert.ok(site2.lastAccessed > Date.now() - 60 * 1000, "lastAccessed for example.org happened recently");
await SiteDataTestUtils.clear();
});
add_task(async function testGetTotalUsage() {
await SiteDataManager.updateSites();
let sites = await SiteDataManager.getSites();
Assert.equal(sites.length, 0, "SiteDataManager is empty");
await SiteDataTestUtils.addToIndexedDB(EXAMPLE_ORIGIN, 4096);
await SiteDataTestUtils.addToIndexedDB(EXAMPLE_ORIGIN_2, 2048);
await SiteDataManager.updateSites();
let usage = await SiteDataManager.getTotalUsage();
Assert.greater(usage, 4096 + 2048, "Has the correct total usage.");
await SiteDataTestUtils.clear();
});
add_task(async function testRemove() {
await SiteDataManager.updateSites();
let uri = Services.io.newURI(EXAMPLE_ORIGIN);
Services.perms.add(uri, "camera", Services.perms.ALLOW_ACTION);
SiteDataTestUtils.addToCookies(EXAMPLE_ORIGIN, "foo1", "bar1");
SiteDataTestUtils.addToCookies(EXAMPLE_ORIGIN, "foo2", "bar2");
await SiteDataTestUtils.addToIndexedDB(EXAMPLE_ORIGIN, 4096);
SiteDataTestUtils.addToCookies(EXAMPLE_ORIGIN_2, "foo", "bar");
await SiteDataTestUtils.addToIndexedDB(EXAMPLE_ORIGIN_2, 2048);
await SiteDataTestUtils.persist(EXAMPLE_ORIGIN_2);
await SiteDataManager.updateSites();
let sites = await SiteDataManager.getSites();
Assert.equal(sites.length, 2, "Has two sites.");
await SiteDataManager.remove(["www.example.com"]);
sites = await SiteDataManager.getSites();
Assert.equal(sites.length, 1, "Has one site.");
Assert.equal(sites[0].host, "example.org", "Has not cleared data for example.org");
let usage = await SiteDataTestUtils.getQuotaUsage(EXAMPLE_ORIGIN);
Assert.equal(usage, 0, "Has cleared quota usage for example.com");
let cookies = Services.cookies.countCookiesFromHost("example.com");
Assert.equal(cookies, 0, "Has cleared cookies for example.com");
let perm = Services.perms.testPermission(uri, "persistent-storage");
Assert.equal(perm, Services.perms.UNKNOWN_ACTION, "Cleared the persistent-storage permission.");
perm = Services.perms.testPermission(uri, "camera");
Assert.equal(perm, Services.perms.ALLOW_ACTION, "Did not clear other permissions.");
Services.perms.remove(uri, "camera");
});
add_task(async function testRemoveSiteData() {
let uri = Services.io.newURI(EXAMPLE_ORIGIN);
Services.perms.add(uri, "camera", Services.perms.ALLOW_ACTION);
SiteDataTestUtils.addToCookies(EXAMPLE_ORIGIN, "foo1", "bar1");
SiteDataTestUtils.addToCookies(EXAMPLE_ORIGIN, "foo2", "bar2");
await SiteDataTestUtils.addToIndexedDB(EXAMPLE_ORIGIN, 4096);
SiteDataTestUtils.addToCookies(EXAMPLE_ORIGIN_2, "foo", "bar");
await SiteDataTestUtils.addToIndexedDB(EXAMPLE_ORIGIN_2, 2048);
await SiteDataTestUtils.persist(EXAMPLE_ORIGIN_2);
await SiteDataManager.updateSites();
let sites = await SiteDataManager.getSites();
Assert.equal(sites.length, 2, "Has two sites.");
await SiteDataManager.removeSiteData();
sites = await SiteDataManager.getSites();
Assert.equal(sites.length, 0, "Has no sites.");
let usage = await SiteDataTestUtils.getQuotaUsage(EXAMPLE_ORIGIN);
Assert.equal(usage, 0, "Has cleared quota usage for example.com");
usage = await SiteDataTestUtils.getQuotaUsage(EXAMPLE_ORIGIN_2);
Assert.equal(usage, 0, "Has cleared quota usage for example.org");
let cookies = Services.cookies.countCookiesFromHost("example.org");
Assert.equal(cookies, 0, "Has cleared cookies for example.org");
let perm = Services.perms.testPermission(uri, "persistent-storage");
Assert.equal(perm, Services.perms.UNKNOWN_ACTION, "Cleared the persistent-storage permission.");
perm = Services.perms.testPermission(uri, "camera");
Assert.equal(perm, Services.perms.ALLOW_ACTION, "Did not clear other permissions.");
Services.perms.remove(uri, "camera");
});

Просмотреть файл

@ -8,6 +8,5 @@ skip-if = toolkit == 'android'
[test_LiveBookmarkMigrator.js]
[test_Sanitizer_interrupted.js]
[test_SitePermissions.js]
[test_SiteDataManager.js]
[test_LaterRun.js]
[test_discovery.js]