forked from mirrors/gecko-dev
180 lines
8.4 KiB
JavaScript
180 lines
8.4 KiB
JavaScript
"use strict";
|
|
|
|
const {XPCOMUtils} = ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
|
|
const {OS} = ChromeUtils.import("resource://gre/modules/osfile.jsm");
|
|
const {Sqlite} = ChromeUtils.import("resource://gre/modules/Sqlite.jsm");
|
|
const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
|
|
XPCOMUtils.defineLazyServiceGetter(this, "TrackingDBService",
|
|
"@mozilla.org/tracking-db-service;1",
|
|
"nsITrackingDBService");
|
|
|
|
XPCOMUtils.defineLazyGetter(this, "DB_PATH", function() {
|
|
return OS.Path.join(OS.Constants.Path.profileDir, "protections.sqlite");
|
|
});
|
|
|
|
const SQL = {
|
|
insertCustomTimeEvent:
|
|
"INSERT INTO events (type, count, timestamp)" +
|
|
"VALUES (:type, :count, date(:timestamp));",
|
|
|
|
selectAllEntriesOfType:
|
|
"SELECT * FROM events WHERE type = :type;",
|
|
|
|
selectAll:
|
|
"SELECT * FROM events",
|
|
};
|
|
|
|
// Emulate the content blocking log. We do not record the url key, nor
|
|
// do we use the aggregated event number (the last element in the array).
|
|
const LOG = {
|
|
"https://1.example.com": [
|
|
[Ci.nsIWebProgressListener.STATE_BLOCKED_TRACKING_CONTENT, true, 1]],
|
|
"https://2.example.com": [
|
|
[Ci.nsIWebProgressListener.STATE_BLOCKED_FINGERPRINTING_CONTENT, true, 1]],
|
|
"https://3.example.com": [
|
|
[Ci.nsIWebProgressListener.STATE_BLOCKED_CRYPTOMINING_CONTENT, true, 2]],
|
|
"https://4.example.com": [
|
|
[Ci.nsIWebProgressListener.STATE_COOKIES_BLOCKED_TRACKER, true, 3]],
|
|
"https://5.example.com": [
|
|
[Ci.nsIWebProgressListener.STATE_COOKIES_BLOCKED_TRACKER, true, 1]],
|
|
// Cookie blocked for other reason, then identified as a tracker
|
|
"https://6.example.com": [
|
|
[Ci.nsIWebProgressListener.STATE_COOKIES_BLOCKED_ALL |
|
|
Ci.nsIWebProgressListener.STATE_LOADED_TRACKING_CONTENT, true, 4]],
|
|
|
|
// The contents below should not add to the database.
|
|
// Cookie loaded but not blocked.
|
|
"https://7.example.com": [
|
|
[Ci.nsIWebProgressListener.STATE_COOKIES_LOADED, true, 1]],
|
|
// Cookie blocked for other reason (not a tracker)
|
|
"https://8.example.com": [
|
|
[Ci.nsIWebProgressListener.STATE_COOKIES_BLOCKED_BY_PERMISSION, true, 2]],
|
|
// Fingerprinters set to block, but this one has an exception
|
|
"https://9.example.com": [
|
|
[Ci.nsIWebProgressListener.STATE_BLOCKED_FINGERPRINTING_CONTENT, false, 1]],
|
|
};
|
|
|
|
do_get_profile();
|
|
|
|
// This tests that data is added successfully, different types of events should get
|
|
// their own entries, when the type is the same they should be aggregated. Events
|
|
// that are not blocking events should not be recorded. Cookie blocking events
|
|
// should only be recorded if we can identify the cookie as a tracking cookie.
|
|
add_task(async function test_save_and_delete() {
|
|
Services.prefs.setBoolPref("browser.contentblocking.database.enabled", true);
|
|
await TrackingDBService.saveEvents(JSON.stringify(LOG));
|
|
|
|
// Peek in the DB to make sure we have the right data.
|
|
let db = await Sqlite.openConnection({ path: DB_PATH });
|
|
// Make sure the items table was created.
|
|
ok((await db.tableExists("events")), "events table exists");
|
|
|
|
// make sure we have the correct contents in the database
|
|
let rows = await db.execute(SQL.selectAll);
|
|
equal(rows.length, 4, "Events that should not be saved have not been, length is 4");
|
|
rows = await db.execute(SQL.selectAllEntriesOfType, {type: TrackingDBService.TRACKERS_ID});
|
|
equal(rows.length, 1, "Only one day has had tracker entries, length is 1");
|
|
let count = rows[0].getResultByName("count");
|
|
equal(count, 1, "there is only one tracker entry");
|
|
|
|
rows = await db.execute(SQL.selectAllEntriesOfType, {type: TrackingDBService.TRACKING_COOKIES_ID});
|
|
equal(rows.length, 1, "Only one day has had cookies entries, length is 1");
|
|
count = rows[0].getResultByName("count");
|
|
equal(count, 3, "Cookie entries were aggregated");
|
|
|
|
rows = await db.execute(SQL.selectAllEntriesOfType, {type: TrackingDBService.CRYPTOMINERS_ID});
|
|
equal(rows.length, 1, "Only one day has had cryptominer entries, length is 1");
|
|
count = rows[0].getResultByName("count");
|
|
equal(count, 1, "there is only one cryptominer entry");
|
|
|
|
rows = await db.execute(SQL.selectAllEntriesOfType, {type: TrackingDBService.FINGERPRINTERS_ID});
|
|
equal(rows.length, 1, "Only one day has had fingerprinters entries, length is 1");
|
|
count = rows[0].getResultByName("count");
|
|
equal(count, 1, "there is only one fingerprinter entry");
|
|
|
|
// Use the TrackingDBService API to delete the data.
|
|
await TrackingDBService.clearAll();
|
|
// Make sure the data was deleted.
|
|
rows = await db.execute(SQL.selectAll);
|
|
equal(rows.length, 0, "length is 0");
|
|
await db.close();
|
|
Services.prefs.clearUserPref("browser.contentblocking.database.enabled");
|
|
});
|
|
|
|
// This tests that content blocking events encountered on the same day get aggregated,
|
|
// and those on different days get seperate entries
|
|
add_task(async function test_timestamp_aggragation() {
|
|
Services.prefs.setBoolPref("browser.contentblocking.database.enabled", true);
|
|
// This creates the schema.
|
|
await TrackingDBService.saveEvents(JSON.stringify({}));
|
|
let db = await Sqlite.openConnection({ path: DB_PATH });
|
|
|
|
let yesterday = new Date(Date.now() - (24 * 60 * 60 * 1000)).toISOString();
|
|
let today = new Date().toISOString();
|
|
await db.execute(SQL.insertCustomTimeEvent, {type: TrackingDBService.TRACKERS_ID, count: 4, timestamp: yesterday});
|
|
await db.execute(SQL.insertCustomTimeEvent, {type: TrackingDBService.CRYPTOMINERS_ID, count: 3, timestamp: yesterday});
|
|
await db.execute(SQL.insertCustomTimeEvent, {type: TrackingDBService.FINGERPRINTERS_ID, count: 2, timestamp: yesterday});
|
|
await db.execute(SQL.insertCustomTimeEvent, {type: TrackingDBService.TRACKING_COOKIES_ID, count: 1, timestamp: yesterday});
|
|
|
|
// Add some events for today which must get aggregated
|
|
await db.execute(SQL.insertCustomTimeEvent, {type: TrackingDBService.TRACKERS_ID, count: 2, timestamp: today});
|
|
await db.execute(SQL.insertCustomTimeEvent, {type: TrackingDBService.CRYPTOMINERS_ID, count: 2, timestamp: today});
|
|
await db.execute(SQL.insertCustomTimeEvent, {type: TrackingDBService.FINGERPRINTERS_ID, count: 2, timestamp: today});
|
|
await db.execute(SQL.insertCustomTimeEvent, {type: TrackingDBService.TRACKING_COOKIES_ID, count: 2, timestamp: today});
|
|
|
|
// Add new events, they will have today's timestamp.
|
|
await TrackingDBService.saveEvents(JSON.stringify(LOG));
|
|
|
|
// Ensure events that are inserted today are not aggregated with past events.
|
|
let rows = await db.execute(SQL.selectAllEntriesOfType, {type: TrackingDBService.TRACKERS_ID});
|
|
equal(rows.length, 2, "Tracker entries for today and yesterday, length is 2");
|
|
for (let i = 0; i < rows.length; i++) {
|
|
let count = rows[i].getResultByName("count");
|
|
if (i == 0) {
|
|
equal(count, 4, "Yesterday's count is 4");
|
|
} else if (i == 1) {
|
|
equal(count, 3, "Today's count is 3, new entries were aggregated");
|
|
}
|
|
}
|
|
|
|
rows = await db.execute(SQL.selectAllEntriesOfType, {type: TrackingDBService.CRYPTOMINERS_ID});
|
|
equal(rows.length, 2, "Cryptominer entries for today and yesterday, length is 2");
|
|
for (let i = 0; i < rows.length; i++) {
|
|
let count = rows[i].getResultByName("count");
|
|
if (i == 0) {
|
|
equal(count, 3, "Yesterday's count is 3");
|
|
} else if (i == 1) {
|
|
equal(count, 3, "Today's count is 3, new entries were aggregated");
|
|
}
|
|
}
|
|
|
|
rows = await db.execute(SQL.selectAllEntriesOfType, {type: TrackingDBService.FINGERPRINTERS_ID});
|
|
equal(rows.length, 2, "Fingerprinter entries for today and yesterday, length is 2");
|
|
for (let i = 0; i < rows.length; i++) {
|
|
let count = rows[i].getResultByName("count");
|
|
if (i == 0) {
|
|
equal(count, 2, "Yesterday's count is 2");
|
|
} else if (i == 1) {
|
|
equal(count, 3, "Today's count is 3, new entries were aggregated");
|
|
}
|
|
}
|
|
|
|
rows = await db.execute(SQL.selectAllEntriesOfType, {type: TrackingDBService.TRACKING_COOKIES_ID});
|
|
equal(rows.length, 2, "Tracking Cookies entries for today and yesterday, length is 2");
|
|
for (let i = 0; i < rows.length; i++) {
|
|
let count = rows[i].getResultByName("count");
|
|
if (i == 0) {
|
|
equal(count, 1, "Yesterday's count is 1");
|
|
} else if (i == 1) {
|
|
equal(count, 5, "Today's count is 5, new entries were aggregated");
|
|
}
|
|
}
|
|
|
|
// Use the TrackingDBService API to delete the data.
|
|
await TrackingDBService.clearAll();
|
|
// Make sure the data was deleted.
|
|
rows = await db.execute(SQL.selectAll);
|
|
equal(rows.length, 0, "length is 0");
|
|
await db.close();
|
|
Services.prefs.clearUserPref("browser.contentblocking.database.enabled");
|
|
});
|