Source code

Revision control

Copy as Markdown

Other Tools

Test Info:

/* Any copyright is dedicated to the Public Domain.
"use strict";
const { XPCOMUtils } = ChromeUtils.importESModule(
"resource://gre/modules/XPCOMUtils.sys.mjs"
);
const { PrivacyMetricsService } = ChromeUtils.importESModule(
"moz-src:///browser/components/protections/PrivacyMetricsService.sys.mjs"
);
const { Sqlite } = ChromeUtils.importESModule(
"resource://gre/modules/Sqlite.sys.mjs"
);
XPCOMUtils.defineLazyServiceGetter(
this,
"TrackingDBService",
"@mozilla.org/tracking-db-service;1",
Ci.nsITrackingDBService
);
ChromeUtils.defineLazyGetter(this, "DB_PATH", function () {
return PathUtils.join(PathUtils.profileDir, "protections.sqlite");
});
const SQL = {
insertCustomTimeEvent:
"INSERT INTO events (type, count, timestamp) " +
"VALUES (:type, :count, date(:timestamp));",
};
// Setup profile and enable tracking database
do_get_profile();
Services.prefs.setBoolPref("browser.contentblocking.database.enabled", true);
add_setup(async function () {
// Initialize the database schema
await TrackingDBService.saveEvents(JSON.stringify({}));
// Clear any existing data before tests
await TrackingDBService.clearAll();
});
registerCleanupFunction(() => {
Services.prefs.clearUserPref("browser.contentblocking.database.enabled");
});
add_task(async function test_getWeeklyStats_empty() {
info("Test that getWeeklyStats returns empty stats for new users");
const stats = await PrivacyMetricsService.getWeeklyStats();
Assert.equal(stats.total, 0, "Total should be 0 for new users");
Assert.equal(stats.trackers, 0, "Trackers should be 0");
Assert.equal(stats.cookies, 0, "Cookies should be 0");
Assert.equal(stats.fingerprinters, 0, "Fingerprinters should be 0");
Assert.equal(stats.cryptominers, 0, "Cryptominers should be 0");
Assert.equal(stats.socialTrackers, 0, "Social trackers should be 0");
Assert.greater(stats.lastUpdated, 0, "Should have a timestamp");
});
add_task(async function test_getWeeklyStats_aggregation() {
info("Test that getWeeklyStats correctly aggregates by category");
const db = await Sqlite.openConnection({ path: DB_PATH });
const now = new Date().toISOString();
// Insert test data directly into database
await db.execute(SQL.insertCustomTimeEvent, {
type: TrackingDBService.TRACKERS_ID,
count: 10,
timestamp: now,
});
await db.execute(SQL.insertCustomTimeEvent, {
type: TrackingDBService.TRACKING_COOKIES_ID,
count: 5,
timestamp: now,
});
await db.execute(SQL.insertCustomTimeEvent, {
type: TrackingDBService.FINGERPRINTERS_ID,
count: 3,
timestamp: now,
});
await db.execute(SQL.insertCustomTimeEvent, {
type: TrackingDBService.CRYPTOMINERS_ID,
count: 2,
timestamp: now,
});
await db.execute(SQL.insertCustomTimeEvent, {
type: TrackingDBService.SOCIAL_ID,
count: 1,
timestamp: now,
});
await db.close();
const stats = await PrivacyMetricsService.getWeeklyStats();
Assert.equal(stats.total, 21, "Total should be sum of all categories");
Assert.equal(stats.trackers, 10, "Trackers counted correctly");
Assert.equal(stats.cookies, 5, "Cookies counted correctly");
Assert.equal(stats.fingerprinters, 3, "Fingerprinters counted correctly");
Assert.equal(stats.cryptominers, 2, "Cryptominers counted correctly");
Assert.equal(stats.socialTrackers, 1, "Social trackers counted correctly");
// Cleanup
await TrackingDBService.clearAll();
});
add_task(async function test_getWeeklyStats_multiple_days() {
info("Test aggregation across multiple days");
const db = await Sqlite.openConnection({ path: DB_PATH });
const now = Date.now();
const oneDayAgo = new Date(now - 24 * 60 * 60 * 1000).toISOString();
const twoDaysAgo = new Date(now - 2 * 24 * 60 * 60 * 1000).toISOString();
const today = new Date().toISOString();
// Day 1 (two days ago)
await db.execute(SQL.insertCustomTimeEvent, {
type: TrackingDBService.TRACKERS_ID,
count: 5,
timestamp: twoDaysAgo,
});
// Day 2 (one day ago)
await db.execute(SQL.insertCustomTimeEvent, {
type: TrackingDBService.TRACKERS_ID,
count: 7,
timestamp: oneDayAgo,
});
// Day 3 (today)
await db.execute(SQL.insertCustomTimeEvent, {
type: TrackingDBService.TRACKERS_ID,
count: 8,
timestamp: today,
});
await db.close();
const stats = await PrivacyMetricsService.getWeeklyStats();
Assert.equal(
stats.trackers,
20,
"Should sum trackers across all days in the week"
);
Assert.equal(stats.total, 20, "Total should equal sum of all categories");
await TrackingDBService.clearAll();
});
add_task(async function test_old_data_ignored() {
info("Test that data older than 7 days is not included");
const db = await Sqlite.openConnection({ path: DB_PATH });
const now = Date.now();
const eightDaysAgo = new Date(now - 8 * 24 * 60 * 60 * 1000).toISOString();
const threeDaysAgo = new Date(now - 3 * 24 * 60 * 60 * 1000).toISOString();
// Add old data (8 days ago)
await db.execute(SQL.insertCustomTimeEvent, {
type: TrackingDBService.TRACKERS_ID,
count: 100,
timestamp: eightDaysAgo,
});
// Add recent data (3 days ago)
await db.execute(SQL.insertCustomTimeEvent, {
type: TrackingDBService.TRACKERS_ID,
count: 50,
timestamp: threeDaysAgo,
});
await db.close();
const stats = await PrivacyMetricsService.getWeeklyStats();
Assert.equal(stats.trackers, 50, "Should only count data from last 7 days");
await TrackingDBService.clearAll();
});
add_task(async function test_exactly_7_days_boundary() {
info("Test 7-day boundary precisely - 6 days ago included, 8 days excluded");
const db = await Sqlite.openConnection({ path: DB_PATH });
const now = Date.now();
// 6 days ago (should be included - within 7-day window)
const sixDaysAgo = new Date(now - 6 * 24 * 60 * 60 * 1000).toISOString();
// 8 days ago (should be excluded - outside 7-day window)
const eightDaysAgo = new Date(now - 8 * 24 * 60 * 60 * 1000).toISOString();
await db.execute(SQL.insertCustomTimeEvent, {
type: TrackingDBService.TRACKERS_ID,
count: 25,
timestamp: sixDaysAgo,
});
await db.execute(SQL.insertCustomTimeEvent, {
type: TrackingDBService.TRACKERS_ID,
count: 75,
timestamp: eightDaysAgo,
});
await db.close();
const stats = await PrivacyMetricsService.getWeeklyStats();
Assert.equal(
stats.trackers,
25,
"Should include 6-day-old data but exclude 8-day-old data"
);
await TrackingDBService.clearAll();
});