Bug 1955948 - Update url classifier exception list tests. r=timhuang,anti-tracking-reviewers

Differential Revision: https://phabricator.services.mozilla.com/D243203
This commit is contained in:
Emma Zuehlcke
2025-04-02 11:25:27 +00:00
parent a19f7962b8
commit cb9c49cf4e
7 changed files with 190 additions and 61 deletions

View File

@@ -23,8 +23,8 @@ add_setup(async function () {
"social-tracking.example.org", "social-tracking.example.org",
], ],
// Whitelist trackertest.org loaded by default in trackingPage.html // Whitelist trackertest.org loaded by default in trackingPage.html
["urlclassifier.trackingSkipURLs", "trackertest.org"], ["urlclassifier.trackingSkipURLs", "*://trackertest.org/*"],
["urlclassifier.trackingAnnotationSkipURLs", "trackertest.org"], ["urlclassifier.trackingAnnotationSkipURLs", "*://trackertest.org/*"],
["privacy.trackingprotection.enabled", false], ["privacy.trackingprotection.enabled", false],
["privacy.trackingprotection.annotate_channels", true], ["privacy.trackingprotection.annotate_channels", true],
], ],

View File

@@ -25,8 +25,8 @@ add_setup(async function () {
["privacy.trackingprotection.fingerprinting.enabled", true], ["privacy.trackingprotection.fingerprinting.enabled", true],
["privacy.socialtracking.block_cookies.enabled", true], ["privacy.socialtracking.block_cookies.enabled", true],
// Allowlist trackertest.org loaded by default in trackingPage.html // Allowlist trackertest.org loaded by default in trackingPage.html
["urlclassifier.trackingSkipURLs", "trackertest.org"], ["urlclassifier.trackingSkipURLs", "*://trackertest.org/*"],
["urlclassifier.trackingAnnotationSkipURLs", "trackertest.org"], ["urlclassifier.trackingAnnotationSkipURLs", "*://trackertest.org/*"],
// Additional denylisted hosts. // Additional denylisted hosts.
[ [
"urlclassifier.trackingAnnotationTable.testEntries", "urlclassifier.trackingAnnotationTable.testEntries",

View File

@@ -22,9 +22,12 @@ UrlClassifierExceptionList::Init(const nsACString& aFeature) {
NS_IMETHODIMP NS_IMETHODIMP
UrlClassifierExceptionList::AddEntry( UrlClassifierExceptionList::AddEntry(
nsIUrlClassifierExceptionListEntry* aEntry) { nsIUrlClassifierExceptionListEntry* aEntry) {
if (!aEntry) { NS_ENSURE_ARG_POINTER(aEntry);
return NS_ERROR_INVALID_ARG;
} nsAutoCString entryString;
Unused << aEntry->Describe(entryString);
UC_LOG_DEBUG(("UrlClassifierExceptionList::%s - Adding entry: %s",
__FUNCTION__, entryString.get()));
mEntries.AppendElement(aEntry); mEntries.AppendElement(aEntry);
return NS_OK; return NS_OK;
@@ -70,4 +73,10 @@ UrlClassifierExceptionList::Matches(nsIURI* aURI, nsIURI* aTopLevelURI,
return NS_OK; return NS_OK;
} }
NS_IMETHODIMP
UrlClassifierExceptionList::TestGetEntries(
nsTArray<RefPtr<nsIUrlClassifierExceptionListEntry>>& aEntries) {
aEntries = mEntries.Clone();
return NS_OK;
}
} // namespace mozilla::net } // namespace mozilla::net

View File

@@ -34,4 +34,10 @@ interface nsIUrlClassifierExceptionList : nsISupports
* @return True if the exception list matches, false otherwise * @return True if the exception list matches, false otherwise
*/ */
boolean matches(in nsIURI aURI, in nsIURI aTopLevelURI, in boolean aIsPrivateBrowsing); boolean matches(in nsIURI aURI, in nsIURI aTopLevelURI, in boolean aIsPrivateBrowsing);
/**
* Test-only interface to get all entries in the exception list.
* @return The entries in the exception list
*/
Array<nsIUrlClassifierExceptionListEntry> testGetEntries();
}; };

View File

@@ -445,8 +445,12 @@ this.AntiTracking = {
].getService(Ci.nsIURIClassifier); ].getService(Ci.nsIURIClassifier);
let feature = classifier.getFeatureByName("tracking-annotation"); let feature = classifier.getFeatureByName("tracking-annotation");
await TestUtils.waitForCondition(() => { await TestUtils.waitForCondition(() => {
for (let x of item[1].toLowerCase().split(",")) { for (let x of item[1].split(",")) {
if (feature.exceptionHostList.split(",").includes(x)) { if (
feature.exceptionList
.testGetEntries()
.some(e => e.urlPattern == x)
) {
return true; return true;
} }
} }

View File

@@ -35,7 +35,7 @@ AntiTracking.runTest(
); );
}); });
}, },
[["urlclassifier.trackingAnnotationSkipURLs", "TRACKING.EXAMPLE.ORG"]], [["urlclassifier.trackingAnnotationSkipURLs", "*://tracking.example.org/*"]],
false, // run the window.open() test false, // run the window.open() test
false, // run the user interaction test false, // run the user interaction test
Ci.nsIWebProgressListener.STATE_COOKIES_BLOCKED_TRACKER, // expect blocking notifications Ci.nsIWebProgressListener.STATE_COOKIES_BLOCKED_TRACKER, // expect blocking notifications
@@ -82,7 +82,7 @@ AntiTracking.runTest(
[ [
[ [
"urlclassifier.trackingAnnotationSkipURLs", "urlclassifier.trackingAnnotationSkipURLs",
"foobar.example,*.example.org,baz.example", "*://foobar.example/*,*://*.example.org/*,*://baz.example/*",
], ],
], ],
false, // run the window.open() test false, // run the window.open() test
@@ -113,7 +113,12 @@ AntiTracking.runTest(
); );
}); });
}, },
[["urlclassifier.trackingAnnotationSkipURLs", "*.tracking.example.org"]], [
[
"urlclassifier.trackingAnnotationSkipURLs",
"*://*.foo.tracking.example.org/*",
],
],
false, // run the window.open() test false, // run the window.open() test
false, // run the user interaction test false, // run the user interaction test
Ci.nsIWebProgressListener.STATE_COOKIES_BLOCKED_TRACKER, // expect blocking notifications Ci.nsIWebProgressListener.STATE_COOKIES_BLOCKED_TRACKER, // expect blocking notifications
@@ -143,7 +148,7 @@ AntiTracking.runTest(
}); });
}, },
[ [
["urlclassifier.trackingAnnotationSkipURLs", "TRACKING.EXAMPLE.ORG"], ["urlclassifier.trackingAnnotationSkipURLs", "*://tracking.example.org/*"],
["privacy.antitracking.enableWebcompat", false], ["privacy.antitracking.enableWebcompat", false],
], ],
false, // run the window.open() test false, // run the window.open() test

View File

@@ -10,7 +10,7 @@ const { RemoteSettings } = ChromeUtils.importESModule(
"resource://services-settings/remote-settings.sys.mjs" "resource://services-settings/remote-settings.sys.mjs"
); );
const COLLECTION_NAME = "url-classifier-skip-urls"; const COLLECTION_NAME = "url-classifier-exceptions";
const FEATURE_TRACKING_NAME = "tracking-annotation-test"; const FEATURE_TRACKING_NAME = "tracking-annotation-test";
const FEATURE_TRACKING_PREF_NAME = "urlclassifier.tracking-annotation-test"; const FEATURE_TRACKING_PREF_NAME = "urlclassifier.tracking-annotation-test";
const FEATURE_SOCIAL_NAME = "socialtracking-annotation-test"; const FEATURE_SOCIAL_NAME = "socialtracking-annotation-test";
@@ -47,8 +47,8 @@ add_task(async function test_list_changes() {
{ {
id: "1", id: "1",
last_modified: 1000000000000001, last_modified: 1000000000000001,
feature: FEATURE_TRACKING_NAME, classifierFeatures: [FEATURE_TRACKING_NAME],
pattern: "example.com", urlPattern: "*://example.com/*",
}, },
]; ];
@@ -63,29 +63,40 @@ add_task(async function test_list_changes() {
obs obs
); );
Assert.equal(await promise, "", "No items in the list"); let list = await promise;
Assert.equal(list.testGetEntries().length, 0, "No items in the list");
// Second event is from the RemoteSettings record. // Second event is from the RemoteSettings record.
let list = await waitForEvent(updateEvent, "update"); list = await waitForEvent(updateEvent, "update");
Assert.equal(list, "example.com", "Has one item in the list");
Assert.equal(list.testGetEntries().length, 1, "Has one item in the list");
Assert.equal(
list.testGetEntries()[0].urlPattern,
"*://example.com/*",
"First item is example.com"
);
records.push( records.push(
// An entry which populates all fields of
// nsIUrlClassifierExceptionListEntry.
{ {
id: "2", id: "2",
last_modified: 1000000000000002, last_modified: 1000000000000002,
feature: FEATURE_TRACKING_NAME, classifierFeatures: [FEATURE_TRACKING_NAME],
pattern: "MOZILLA.ORG", urlPattern: "*://MOZILLA.ORG/*",
topLevelUrlPattern: "*://example.com/*",
isPrivateBrowsingOnly: true,
filterContentBlockingCategories: ["standard"],
}, },
{ {
id: "3", id: "3",
last_modified: 1000000000000003, last_modified: 1000000000000003,
feature: "some-other-feature", classifierFeatures: ["some-other-feature"],
pattern: "noinclude.com", urlPattern: "*://noinclude.com/*",
}, },
{ {
last_modified: 1000000000000004, last_modified: 1000000000000004,
feature: FEATURE_TRACKING_NAME, classifierFeatures: [FEATURE_TRACKING_NAME],
pattern: "*.example.org", urlPattern: "*://*.example.org/*",
} }
); );
@@ -97,37 +108,110 @@ add_task(async function test_list_changes() {
list = await promise; list = await promise;
let entries = list.testGetEntries();
Assert.equal(entries.length, 3, "Has three items in the list");
Assert.equal( Assert.equal(
list, entries[0].urlPattern,
"example.com,mozilla.org,*.example.org", "*://example.com/*",
"Has several items in the list" "First item is example.com"
);
Assert.equal(
entries[1].urlPattern,
"*://MOZILLA.ORG/*",
"Second item is mozilla.org"
);
Assert.equal(
entries[1].topLevelUrlPattern,
"*://example.com/*",
"Top level url pattern of second item is correctly set."
);
Assert.equal(
entries[1].isPrivateBrowsingOnly,
true,
"isPrivateBrowsingOnly flag of second item is correctly set."
);
Assert.deepEqual(
entries[1].filterContentBlockingCategories,
["standard"],
"filterContentBlockingCategories of second item is correctly set."
);
Assert.equal(
entries[2].urlPattern,
"*://*.example.org/*",
"Third item is *.example.org"
); );
promise = waitForEvent(updateEvent, "update"); promise = waitForEvent(updateEvent, "update");
Services.prefs.setStringPref(FEATURE_TRACKING_PREF_NAME, "test.com"); Services.prefs.setStringPref(FEATURE_TRACKING_PREF_NAME, "*://test.com/*");
list = await promise; list = await promise;
entries = list.testGetEntries();
Assert.equal(entries.length, 4, "Has four items in the list");
Assert.equal( Assert.equal(
list, entries[1].urlPattern,
"test.com,example.com,mozilla.org,*.example.org", "*://example.com/*",
"Has several items in the list" "First item is example.com"
);
Assert.equal(
entries[2].urlPattern,
"*://MOZILLA.ORG/*",
"Second item is mozilla.org"
);
Assert.equal(
entries[3].urlPattern,
"*://*.example.org/*",
"Third item is *.example.org"
);
Assert.equal(
entries[0].urlPattern,
"*://test.com/*",
"Fourth item is test.com"
); );
promise = waitForEvent(updateEvent, "update"); promise = waitForEvent(updateEvent, "update");
Services.prefs.setStringPref( Services.prefs.setStringPref(
FEATURE_TRACKING_PREF_NAME, FEATURE_TRACKING_PREF_NAME,
"test.com,whatever.com,*.abc.com" "*://test.com/*,*://whatever.com/*,*://*.abc.com/*"
); );
list = await promise; list = await promise;
entries = list.testGetEntries();
Assert.equal(entries.length, 6, "Has six items in the list");
Assert.equal( Assert.equal(
list, entries[0].urlPattern,
"test.com,whatever.com,*.abc.com,example.com,mozilla.org,*.example.org", "*://test.com/*",
"Has several items in the list" "First item is test.com"
);
Assert.equal(
entries[1].urlPattern,
"*://whatever.com/*",
"Second item is whatever.com"
);
Assert.equal(
entries[2].urlPattern,
"*://*.abc.com/*",
"Third item is *.abc.com"
);
Assert.equal(
entries[3].urlPattern,
"*://example.com/*",
"Fourth item is example.com"
);
Assert.equal(
entries[4].urlPattern,
"*://MOZILLA.ORG/*",
"Fifth item is mozilla.org"
);
Assert.equal(
entries[5].urlPattern,
"*://*.example.org/*",
"Sixth item is *.example.org"
); );
exceptionListService.unregisterExceptionListObserver( exceptionListService.unregisterExceptionListObserver(
@@ -158,26 +242,26 @@ add_task(async function test_list_init_data() {
{ {
id: "1", id: "1",
last_modified: 1000000000000001, last_modified: 1000000000000001,
feature: FEATURE_TRACKING_NAME, classifierFeatures: [FEATURE_TRACKING_NAME],
pattern: "tracking.example.com", urlPattern: "*://tracking.example.com/*",
}, },
{ {
id: "2", id: "2",
last_modified: 1000000000000002, last_modified: 1000000000000002,
feature: FEATURE_SOCIAL_NAME, classifierFeatures: [FEATURE_SOCIAL_NAME],
pattern: "social.example.com", urlPattern: "*://social.example.com/*",
}, },
{ {
id: "3", id: "3",
last_modified: 1000000000000003, last_modified: 1000000000000003,
feature: FEATURE_TRACKING_NAME, classifierFeatures: [FEATURE_TRACKING_NAME],
pattern: "*.tracking.org", urlPattern: "*://*.tracking.org/*",
}, },
{ {
id: "4", id: "4",
last_modified: 1000000000000004, last_modified: 1000000000000004,
feature: FEATURE_SOCIAL_NAME, classifierFeatures: [FEATURE_SOCIAL_NAME],
pattern: "MOZILLA.ORG", urlPattern: "*://MOZILLA.ORG/*",
}, },
]; ];
@@ -200,12 +284,20 @@ add_task(async function test_list_init_data() {
); );
let list = await promise; let list = await promise;
Assert.equal(list, "", "Empty list initially"); Assert.equal(list.testGetEntries().length, 0, "Empty list initially");
list = await waitForEvent(updateEvent, "update");
let entries = list.testGetEntries();
Assert.equal(entries.length, 2, "Has two items in the list");
Assert.equal( Assert.equal(
await waitForEvent(updateEvent, "update"), entries[0].urlPattern,
"tracking.example.com,*.tracking.org", "*://tracking.example.com/*",
"Has several items in the list" "First item is tracking.example.com"
);
Assert.equal(
entries[1].urlPattern,
"*://*.tracking.org/*",
"Second item is *.tracking.org"
); );
// Register another feature after ExceptionListService got the initial data. // Register another feature after ExceptionListService got the initial data.
@@ -218,11 +310,17 @@ add_task(async function test_list_init_data() {
); );
list = await promise; list = await promise;
entries = list.testGetEntries();
Assert.equal(entries.length, 2, "Has two items in the list");
Assert.equal( Assert.equal(
list, entries[0].urlPattern,
"social.example.com,mozilla.org", "*://social.example.com/*",
"Has several items in the list" "First item is social.example.com"
);
Assert.equal(
entries[1].urlPattern,
"*://MOZILLA.ORG/*",
"Second item is mozilla.org"
); );
// Test registering a feature after ExceptionListService recieved the synced data. // Test registering a feature after ExceptionListService recieved the synced data.
@@ -230,20 +328,20 @@ add_task(async function test_list_init_data() {
{ {
id: "5", id: "5",
last_modified: 1000000000000002, last_modified: 1000000000000002,
feature: FEATURE_FINGERPRINTING_NAME, classifierFeatures: [FEATURE_FINGERPRINTING_NAME],
pattern: "fingerprinting.example.com", urlPattern: "*://fingerprinting.example.com/*",
}, },
{ {
id: "6", id: "6",
last_modified: 1000000000000002, last_modified: 1000000000000002,
feature: "other-fature", classifierFeatures: ["other-feature"],
pattern: "not-a-fingerprinting.example.com", urlPattern: "*://not-a-fingerprinting.example.com/*",
}, },
{ {
id: "7", id: "7",
last_modified: 1000000000000002, last_modified: 1000000000000002,
feature: FEATURE_FINGERPRINTING_NAME, classifierFeatures: [FEATURE_FINGERPRINTING_NAME],
pattern: "*.fingerprinting.org", urlPattern: "*://*.fingerprinting.org/*",
} }
); );
@@ -261,10 +359,17 @@ add_task(async function test_list_init_data() {
list = await promise; list = await promise;
entries = list.testGetEntries();
Assert.equal(entries.length, 2, "Has two items in the list");
Assert.equal( Assert.equal(
list, entries[0].urlPattern,
"fingerprinting.example.com,*.fingerprinting.org", "*://fingerprinting.example.com/*",
"Has several items in the list" "First item is fingerprinting.example.com"
);
Assert.equal(
entries[1].urlPattern,
"*://*.fingerprinting.org/*",
"Second item is *.fingerprinting.org"
); );
exceptionListService.unregisterExceptionListObserver( exceptionListService.unregisterExceptionListObserver(