572 lines
17 KiB
JavaScript
572 lines
17 KiB
JavaScript
/* Any copyright is dedicated to the Public Domain.
|
|
* http://creativecommons.org/publicdomain/zero/1.0/
|
|
*/
|
|
"use strict";
|
|
|
|
ChromeUtils.defineESModuleGetters(this, {
|
|
SiteDataManager: "resource:///modules/SiteDataManager.sys.mjs",
|
|
SiteDataTestUtils: "resource://testing-common/SiteDataTestUtils.sys.mjs",
|
|
PermissionTestUtils: "resource://testing-common/PermissionTestUtils.sys.mjs",
|
|
Downloads: "resource://gre/modules/Downloads.sys.mjs",
|
|
FileTestUtils: "resource://testing-common/FileTestUtils.sys.mjs",
|
|
Sanitizer: "resource:///modules/Sanitizer.sys.mjs",
|
|
});
|
|
|
|
const TEST_DOWNLOAD_FILE_NAME = "test-download.txt";
|
|
let fileURL;
|
|
let downloadList;
|
|
var nowMs = Date.now();
|
|
const hoursTodayInMs = new Date() - new Date(new Date().setHours(0, 0, 0, 0));
|
|
|
|
const EXAMPLE_ORIGIN = "https://www.example.com";
|
|
const EXAMPLE_ORIGIN_2 = "https://example.org";
|
|
const EXAMPLE_ORIGIN_3 = "http://localhost:8000";
|
|
const EXAMPLE_ORIGIN_4 = "http://localhost:3000";
|
|
const EXAMPLE_ORIGIN_5 = "http://example.net";
|
|
|
|
const TIMESPANS = [
|
|
"TIMESPAN_HOUR",
|
|
"TIMESPAN_2HOURS",
|
|
"TIMESPAN_4HOURS",
|
|
"TIMESPAN_TODAY",
|
|
"TIMESPAN_EVERYTHING",
|
|
];
|
|
|
|
let oneHourInMs = 60 * 60 * 1000;
|
|
let today = nowMs - new Date().setHours(0, 0, 0, 0);
|
|
|
|
let p =
|
|
Services.scriptSecurityManager.createContentPrincipalFromOrigin(
|
|
EXAMPLE_ORIGIN
|
|
);
|
|
let partitionKey = `(${p.scheme},${p.baseDomain})`;
|
|
let EXAMPLE_ORIGIN_2_PARTITIONED =
|
|
Services.scriptSecurityManager.createContentPrincipal(
|
|
Services.io.newURI(EXAMPLE_ORIGIN_2),
|
|
{
|
|
partitionKey,
|
|
}
|
|
).origin;
|
|
|
|
/**
|
|
* Created a temporary file URL to add to downloads
|
|
*
|
|
* @returns {Object} file URL
|
|
*/
|
|
function createDownloadFileURL() {
|
|
if (!fileURL) {
|
|
let file = Services.dirsvc.get("TmpD", Ci.nsIFile);
|
|
file.append("foo.txt");
|
|
file.createUnique(Ci.nsIFile.NORMAL_FILE_TYPE, 0o600);
|
|
|
|
fileURL = Services.io.newFileURI(file);
|
|
}
|
|
|
|
return fileURL;
|
|
}
|
|
|
|
/**
|
|
* Creates a new download list to populate
|
|
*
|
|
* @returns download list to update
|
|
*/
|
|
async function createDownloadList() {
|
|
if (!downloadList) {
|
|
Downloads._promiseListsInitialized = null;
|
|
Downloads._lists = {};
|
|
Downloads._summaries = {};
|
|
|
|
downloadList = await Downloads.getList(Downloads.ALL);
|
|
}
|
|
|
|
return downloadList;
|
|
}
|
|
|
|
/**
|
|
* Add sites through the site data manager based on the site last accessed array
|
|
*
|
|
* @param {number[]} siteLastAccessedArr - array of time's when the site was last accessed
|
|
* e.g. [2, 2, 4, 24 ...]
|
|
* We currently do not have a 24 hour option in the dialog, so we convert 24 to today
|
|
* @param {Object} testSiteUsageDataObj - Object to populate and update
|
|
* @returns testSiteUsageData Object with the quota usage for each timespan
|
|
*/
|
|
async function addSitesWithLastAccessed(
|
|
siteLastAccessedArr,
|
|
testSiteUsageDataObj
|
|
) {
|
|
let SITE_ORIGINS = [
|
|
EXAMPLE_ORIGIN,
|
|
EXAMPLE_ORIGIN_2,
|
|
EXAMPLE_ORIGIN_5,
|
|
EXAMPLE_ORIGIN_3,
|
|
EXAMPLE_ORIGIN_4,
|
|
EXAMPLE_ORIGIN_2_PARTITIONED,
|
|
];
|
|
|
|
let staticUsage = 4096;
|
|
// Add a time buffer so the site access falls within the time range
|
|
const buffer = 100000;
|
|
|
|
// Change lastAccessed of sites
|
|
for (let index = 0; index < siteLastAccessedArr.length; index++) {
|
|
testSiteUsageDataObj[siteLastAccessedArr[index]] += staticUsage;
|
|
// subtract 1 to make sure the added site is within the time range
|
|
let lastAccessedTime = Sanitizer.timeSpanMsMap[siteLastAccessedArr[index]];
|
|
let site = SiteDataManager._testInsertSite(SITE_ORIGINS[index], {
|
|
quotaUsage: staticUsage,
|
|
lastAccessed: (nowMs - lastAccessedTime + buffer) * 1000,
|
|
});
|
|
Assert.ok(
|
|
site,
|
|
`Site added successfully with last accessed ${new Date(
|
|
site.lastAccessed
|
|
)}`
|
|
);
|
|
}
|
|
|
|
let cumulativeSum = 0;
|
|
for (let key in testSiteUsageDataObj) {
|
|
cumulativeSum += testSiteUsageDataObj[key];
|
|
testSiteUsageDataObj[key] = cumulativeSum;
|
|
}
|
|
// account for items being added within today that overlap other time ranges
|
|
// this is to account for edge cases for when this test might be run near after midnight
|
|
// We only care about the timespans until TIMESPAN_TODAY (i<3)
|
|
if (hoursTodayInMs < Sanitizer.timeSpanMsMap.TIMESPAN_HOUR) {
|
|
testSiteUsageDataObj.TIMESPAN_HOUR += testSiteUsageDataObj.TIMESPAN_TODAY;
|
|
}
|
|
if (hoursTodayInMs < Sanitizer.timeSpanMsMap.TIMESPAN_2HOURS) {
|
|
testSiteUsageDataObj.TIMESPAN_2HOURS += testSiteUsageDataObj.TIMESPAN_TODAY;
|
|
}
|
|
if (hoursTodayInMs < Sanitizer.timeSpanMsMap.TIMESPAN_4HOURS) {
|
|
testSiteUsageDataObj.TIMESPAN_4HOURS += testSiteUsageDataObj.TIMESPAN_TODAY;
|
|
}
|
|
|
|
return testSiteUsageDataObj;
|
|
}
|
|
|
|
add_task(function setup() {
|
|
do_get_profile();
|
|
});
|
|
|
|
add_task(async function testGetSites() {
|
|
SiteDataTestUtils.addToCookies({
|
|
origin: EXAMPLE_ORIGIN,
|
|
name: "foo1",
|
|
value: "bar1",
|
|
});
|
|
SiteDataTestUtils.addToCookies({
|
|
origin: EXAMPLE_ORIGIN,
|
|
name: "foo2",
|
|
value: "bar2",
|
|
});
|
|
|
|
// Cookie of EXAMPLE_ORIGIN_2 partitioned under EXAMPLE_ORIGIN.
|
|
SiteDataTestUtils.addToCookies({
|
|
origin: EXAMPLE_ORIGIN_2_PARTITIONED,
|
|
name: "foo3",
|
|
value: "bar3",
|
|
});
|
|
// IndexedDB storage of EXAMPLE_ORIGIN_2 partitioned under EXAMPLE_ORIGIN.
|
|
await SiteDataTestUtils.addToIndexedDB(EXAMPLE_ORIGIN, 4096);
|
|
await SiteDataTestUtils.addToIndexedDB(EXAMPLE_ORIGIN_2_PARTITIONED, 4096);
|
|
SiteDataTestUtils.addToCookies({
|
|
origin: EXAMPLE_ORIGIN_2,
|
|
name: "foo",
|
|
value: "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"
|
|
);
|
|
// 4096 partitioned + 4096 unpartitioned.
|
|
Assert.greater(site1.usage, 4096 * 2, "Has correct usage for example.com");
|
|
Assert.equal(site1.persisted, false, "example.com is not persisted");
|
|
Assert.equal(
|
|
site1.cookies.length,
|
|
3, // 2 top level, 1 partitioned.
|
|
"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.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);
|
|
PermissionTestUtils.add(uri, "camera", Services.perms.ALLOW_ACTION);
|
|
|
|
SiteDataTestUtils.addToCookies({
|
|
origin: EXAMPLE_ORIGIN,
|
|
name: "foo1",
|
|
value: "bar1",
|
|
});
|
|
SiteDataTestUtils.addToCookies({
|
|
origin: EXAMPLE_ORIGIN,
|
|
name: "foo2",
|
|
value: "bar2",
|
|
});
|
|
SiteDataTestUtils.addToCookies({
|
|
origin: EXAMPLE_ORIGIN_2_PARTITIONED,
|
|
name: "foo3",
|
|
value: "bar3",
|
|
});
|
|
await SiteDataTestUtils.addToIndexedDB(EXAMPLE_ORIGIN, 4096);
|
|
await SiteDataTestUtils.addToIndexedDB(EXAMPLE_ORIGIN_2_PARTITIONED, 4096);
|
|
SiteDataTestUtils.addToCookies({
|
|
origin: EXAMPLE_ORIGIN_2,
|
|
name: "foo",
|
|
value: "bar",
|
|
});
|
|
await SiteDataTestUtils.addToIndexedDB(EXAMPLE_ORIGIN_2, 2048);
|
|
await SiteDataTestUtils.persist(EXAMPLE_ORIGIN_2);
|
|
await SiteDataTestUtils.addToIndexedDB(EXAMPLE_ORIGIN_3, 2048);
|
|
|
|
await SiteDataManager.updateSites();
|
|
|
|
let sites = await SiteDataManager.getSites();
|
|
|
|
Assert.equal(sites.length, 3, "Has three sites.");
|
|
|
|
await SiteDataManager.remove("localhost");
|
|
|
|
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].baseDomain,
|
|
"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 = PermissionTestUtils.testPermission(uri, "persistent-storage");
|
|
Assert.equal(
|
|
perm,
|
|
Services.perms.UNKNOWN_ACTION,
|
|
"Cleared the persistent-storage permission."
|
|
);
|
|
perm = PermissionTestUtils.testPermission(uri, "camera");
|
|
Assert.equal(
|
|
perm,
|
|
Services.perms.ALLOW_ACTION,
|
|
"Did not clear other permissions."
|
|
);
|
|
|
|
PermissionTestUtils.remove(uri, "camera");
|
|
});
|
|
|
|
add_task(async function testRemoveSiteData() {
|
|
let uri = Services.io.newURI(EXAMPLE_ORIGIN);
|
|
PermissionTestUtils.add(uri, "camera", Services.perms.ALLOW_ACTION);
|
|
|
|
SiteDataTestUtils.addToCookies({
|
|
origin: EXAMPLE_ORIGIN,
|
|
name: "foo1",
|
|
value: "bar1",
|
|
});
|
|
SiteDataTestUtils.addToCookies({
|
|
origin: EXAMPLE_ORIGIN,
|
|
name: "foo2",
|
|
value: "bar2",
|
|
});
|
|
SiteDataTestUtils.addToCookies({
|
|
origin: EXAMPLE_ORIGIN_2_PARTITIONED,
|
|
name: "foo3",
|
|
value: "bar3",
|
|
});
|
|
await SiteDataTestUtils.addToIndexedDB(EXAMPLE_ORIGIN, 4096);
|
|
await SiteDataTestUtils.addToIndexedDB(EXAMPLE_ORIGIN_2_PARTITIONED, 4096);
|
|
SiteDataTestUtils.addToCookies({
|
|
origin: EXAMPLE_ORIGIN_2,
|
|
name: "foo",
|
|
value: "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 = PermissionTestUtils.testPermission(uri, "persistent-storage");
|
|
Assert.equal(
|
|
perm,
|
|
Services.perms.UNKNOWN_ACTION,
|
|
"Cleared the persistent-storage permission."
|
|
);
|
|
perm = PermissionTestUtils.testPermission(uri, "camera");
|
|
Assert.equal(
|
|
perm,
|
|
Services.perms.ALLOW_ACTION,
|
|
"Did not clear other permissions."
|
|
);
|
|
|
|
PermissionTestUtils.remove(uri, "camera");
|
|
});
|
|
|
|
add_task(async function testDownloadDataSizeByRange() {
|
|
Services.prefs.setBoolPref("privacy.cpd.downloads", true);
|
|
|
|
let url = createDownloadFileURL();
|
|
let list = await createDownloadList();
|
|
|
|
let testSizes = [3, 1, 2, 2, 2];
|
|
let timeMultiplier = [0.5, 2, 4, 24, 56];
|
|
|
|
// Add a time buffer so the download falls within the time range
|
|
let buffer = 100000;
|
|
let totalItems = 0;
|
|
|
|
for (let i = 0; i < testSizes.length; i++) {
|
|
totalItems += testSizes[i];
|
|
let setTime = nowMs - oneHourInMs * timeMultiplier[i] + buffer;
|
|
if (timeMultiplier[i] === 24) {
|
|
setTime = nowMs - today + buffer;
|
|
}
|
|
// Add downloads to downloads list
|
|
for (let j = 0; j < testSizes[i]; j++) {
|
|
let download = await Downloads.createDownload({
|
|
source: { url: url.spec, isPrivate: false },
|
|
target: {
|
|
path: FileTestUtils.getTempFile(TEST_DOWNLOAD_FILE_NAME).path,
|
|
},
|
|
startTime: {
|
|
getTime: _ => {
|
|
return setTime;
|
|
},
|
|
},
|
|
});
|
|
|
|
Assert.ok(
|
|
!!download,
|
|
`The download for ${timeMultiplier[i]} was created successfully!`
|
|
);
|
|
|
|
list.add(download);
|
|
}
|
|
}
|
|
|
|
let items = await list.getAll();
|
|
Assert.equal(items.length, totalItems, "Items were added to the list");
|
|
|
|
let rangedSize = await SiteDataManager.getDownloadCountForTimeRanges(
|
|
TIMESPANS
|
|
);
|
|
|
|
let compareSizes = [0, 0, 0, 0, 0];
|
|
|
|
// account for items being added within today that overlap other time ranges
|
|
// this is to account for edge cases for when this test might be run near after midnight
|
|
// we only care about i = 3 since that is the index where TIMESPAN_TODAY lives
|
|
if (hoursTodayInMs < Sanitizer.timeSpanMsMap.TIMESPAN_HOUR) {
|
|
compareSizes[0] += testSizes[3];
|
|
}
|
|
if (hoursTodayInMs < Sanitizer.timeSpanMsMap.TIMESPAN_2HOURS) {
|
|
compareSizes[1] += testSizes[3];
|
|
}
|
|
if (hoursTodayInMs < Sanitizer.timeSpanMsMap.TIMESPAN_4HOURS) {
|
|
compareSizes[2] += testSizes[3];
|
|
}
|
|
// add all the sizes to reflect total size for a range
|
|
for (let max = 0; max < testSizes.length; max++) {
|
|
for (let i = 0; i <= max; i++) {
|
|
compareSizes[max] += testSizes[i];
|
|
}
|
|
}
|
|
|
|
// check the timerange array against the expected sizes
|
|
// we use TIMESPANS[] to get the key for rangedSize we are comparing
|
|
for (let i = 0; i < testSizes.length; i++) {
|
|
Assert.equal(
|
|
compareSizes[i],
|
|
rangedSize[TIMESPANS[i]],
|
|
"Checking time range array"
|
|
);
|
|
}
|
|
|
|
// Clear last 4 hours
|
|
Services.prefs.setIntPref(Sanitizer.PREF_TIMESPAN, Sanitizer.TIMESPAN_4HOURS);
|
|
await Sanitizer.sanitize(null, { ignoreTimespan: false });
|
|
|
|
// reset testsizes
|
|
testSizes[0] = 0;
|
|
testSizes[1] = 0;
|
|
testSizes[2] = 0;
|
|
|
|
rangedSize = await SiteDataManager.getDownloadCountForTimeRanges(TIMESPANS);
|
|
|
|
compareSizes = [0, 0, 0, 0, 0];
|
|
|
|
// account for items being added within today that overlap other time ranges
|
|
// this is to account for edge cases for when this test might be run near after midnight
|
|
// we only care about i = 3 since that is the index where TIMESPAN_TODAY lives
|
|
if (hoursTodayInMs < Sanitizer.timeSpanMsMap.TIMESPAN_HOUR) {
|
|
compareSizes[0] += testSizes[3];
|
|
}
|
|
if (hoursTodayInMs < Sanitizer.timeSpanMsMap.TIMESPAN_2HOURS) {
|
|
compareSizes[1] += testSizes[3];
|
|
}
|
|
if (hoursTodayInMs < Sanitizer.timeSpanMsMap.TIMESPAN_4HOURS) {
|
|
compareSizes[2] += testSizes[3];
|
|
}
|
|
// add all the sizes to reflect total size for a range
|
|
for (let max = 0; max < testSizes.length; max++) {
|
|
for (let i = 0; i <= max; i++) {
|
|
compareSizes[max] += testSizes[i];
|
|
}
|
|
}
|
|
|
|
// check the timerange array against the expected sizes
|
|
// we use TIMESPANS[] to get the key for rangedSize we are comparing
|
|
for (let i = 0; i < testSizes.length; i++) {
|
|
Assert.equal(
|
|
compareSizes[i],
|
|
rangedSize[TIMESPANS[i]],
|
|
"Checking time range array"
|
|
);
|
|
}
|
|
|
|
// Clear all downloads
|
|
await new Promise(resolve => {
|
|
Services.clearData.deleteData(
|
|
Ci.nsIClearDataService.CLEAR_DOWNLOADS,
|
|
value => {
|
|
Assert.equal(value, 0);
|
|
resolve();
|
|
}
|
|
);
|
|
});
|
|
|
|
items = await list.getAll();
|
|
Assert.equal(items.length, 0, "Delete all downloaded items for test");
|
|
});
|
|
|
|
add_task(async function testGetQuotaUsageByRange() {
|
|
await SiteDataManager.updateSites();
|
|
|
|
let sites = await SiteDataManager.getSites();
|
|
Assert.equal(sites.length, 0, "SiteDataManager is empty");
|
|
|
|
let testSiteUsageData = {
|
|
TIMESPAN_HOUR: 0,
|
|
TIMESPAN_2HOURS: 0,
|
|
TIMESPAN_4HOURS: 0,
|
|
TIMESPAN_TODAY: 0,
|
|
TIMESPAN_EVERYTHING: 0,
|
|
};
|
|
|
|
testSiteUsageData = await addSitesWithLastAccessed(
|
|
[
|
|
"TIMESPAN_HOUR",
|
|
"TIMESPAN_2HOURS",
|
|
"TIMESPAN_2HOURS",
|
|
"TIMESPAN_4HOURS",
|
|
"TIMESPAN_TODAY",
|
|
"TIMESPAN_EVERYTHING",
|
|
],
|
|
testSiteUsageData
|
|
);
|
|
|
|
let usageObj = await SiteDataManager.getQuotaUsageForTimeRanges(TIMESPANS);
|
|
|
|
let index = 0;
|
|
for (let key in testSiteUsageData) {
|
|
Assert.equal(
|
|
usageObj[TIMESPANS[index]],
|
|
testSiteUsageData[key],
|
|
`Usage data is correct for ${key} hrs`
|
|
);
|
|
index++;
|
|
}
|
|
|
|
await SiteDataTestUtils.clear();
|
|
});
|