/* Any copyright is dedicated to the Public Domain. https://creativecommons.org/publicdomain/zero/1.0/ */ "use strict"; const { TestUtils } = ChromeUtils.importESModule( "resource://testing-common/TestUtils.sys.mjs" ); const { UrlClassifierTestUtils } = ChromeUtils.importESModule( "resource://testing-common/UrlClassifierTestUtils.sys.mjs" ); let btp; let bounceTrackingGracePeriodSec; /** * Wait for purge telemetry to be recorded for a list of site hosts. * * @param {Array} siteHosts - List of site hosts to be purged. */ function waitForPurgeTelemetry(siteHosts) { let expectedSiteHosts = new Set(siteHosts); return TestUtils.topicObserved( "bounce-tracking-protection-recorded-purge-telemetry", (_, siteHost) => { console.debug("observed purge telemetry", siteHost); expectedSiteHosts.delete(siteHost); // Resolve once all expected sites have been observed. return expectedSiteHosts.size == 0; } ); } add_setup(async function () { Services.prefs.setIntPref( "privacy.bounceTrackingProtection.mode", Ci.nsIBounceTrackingProtection.MODE_ENABLED ); btp = Cc["@mozilla.org/bounce-tracking-protection;1"].getService( Ci.nsIBounceTrackingProtection ); // Reset global bounce tracking state. btp.clearAll(); // Clear telemetry state. Services.fog.testResetFOG(); bounceTrackingGracePeriodSec = Services.prefs.getIntPref( "privacy.bounceTrackingProtection.bounceTrackingGracePeriodSec" ); await UrlClassifierTestUtils.addTestTrackers(); registerCleanupFunction(() => { UrlClassifierTestUtils.cleanupTestTrackers(); }); }); add_task(async function test_purging_increments_classified_tracker_counter() { let now = Date.now(); let timestampOutsideGracePeriodThreeDays = now - (bounceTrackingGracePeriodSec + 60 * 60 * 24 * 3) * 1000; let timestampWithinGracePeriod = now - (bounceTrackingGracePeriodSec * 1000) / 2; // Bounce tracker that doesn't get purged. btp.testAddBounceTrackerCandidate( {}, "example.com", timestampWithinGracePeriod * 1000 ); // Bounce tracker that is not classified as a tracker by list. btp.testAddBounceTrackerCandidate( {}, "example.org", timestampOutsideGracePeriodThreeDays * 1000 ); // Bounce trackers that are known trackers. btp.testAddBounceTrackerCandidate( {}, "itisatracker.org", timestampOutsideGracePeriodThreeDays * 1000 ); btp.testAddBounceTrackerCandidate( {}, "trackertest.org", timestampOutsideGracePeriodThreeDays * 1000 ); Assert.equal( Glean.bounceTrackingProtection.purgeCountClassifiedTracker.testGetValue(), null, "No classified trackers purged yet" ); info("Run PurgeBounceTrackers"); let expectedPurgedHosts = [ "example.org", "itisatracker.org", "trackertest.org", ]; let telemetryPromise = waitForPurgeTelemetry(expectedPurgedHosts); let purgedHosts = await btp.testRunPurgeBounceTrackers(); await telemetryPromise; Assert.deepEqual( purgedHosts.sort(), expectedPurgedHosts.sort(), "Purged the correct sites" ); Assert.equal( Glean.bounceTrackingProtection.purgeCountClassifiedTracker.testGetValue(), 2, "Purge counter for classified trackers is correct" ); info("Re-run PurgeBounceTrackers with a known tracker."); btp.testAddBounceTrackerCandidate( {}, "trackertest.org", timestampOutsideGracePeriodThreeDays * 1000 ); telemetryPromise = waitForPurgeTelemetry(["trackertest.org"]); purgedHosts = await btp.testRunPurgeBounceTrackers(); await telemetryPromise; Assert.deepEqual( purgedHosts, ["trackertest.org"], "Purged the correct sites" ); Assert.equal( Glean.bounceTrackingProtection.purgeCountClassifiedTracker.testGetValue(), 3, "Purge counter for classified trackers has been incremented" ); // Reset global bounce tracking state. btp.clearAll(); // Clear telemetry state. Services.fog.testResetFOG(); });