From 5a7ea321332f60aec9fa6395ad85098edc87e93e Mon Sep 17 00:00:00 2001 From: Dave Vandyke Date: Tue, 14 Feb 2023 13:21:33 +0000 Subject: [PATCH] Add Click to Load reference tests (#74) Add reference tests for the Click to Load feature, to ensure that platforms block/allow requests consistently. Notes: - These tests do not include the UI aspects of the feature, such as what the placeholder elements look like. - These changes are heavily based on Konrad's earlier work[1]. 1 - https://github.com/duckduckgo/privacy-reference-tests/pull/30 --- click-to-load/README.md | 71 +++++++++++++++++ click-to-load/config_reference.json | 22 ++++++ click-to-load/surrogates_reference.txt | 2 + click-to-load/tds_reference.json | 69 ++++++++++++++++ click-to-load/tests.json | 104 +++++++++++++++++++++++++ 5 files changed, 268 insertions(+) create mode 100644 click-to-load/README.md create mode 100644 click-to-load/config_reference.json create mode 100644 click-to-load/surrogates_reference.txt create mode 100644 click-to-load/tds_reference.json create mode 100644 click-to-load/tests.json diff --git a/click-to-load/README.md b/click-to-load/README.md new file mode 100644 index 0000000..6254dd9 --- /dev/null +++ b/click-to-load/README.md @@ -0,0 +1,71 @@ +# Click To Load Tests + +Privacy Feature: https://app.asana.com/0/1198207348643509/1199651947726592/f + +## Goals + +This set of tests verifies the Click to Load feature: + +- Blocks/redirects requests when Click to Load is enabled for a tab. +- Ignores those requests when: + - Click to Load isn't enabled for a tab. + - The user clicked to load the content. + - The content is first-party. + - The Click to Load rule action isn't supported. + +These tests do not aim to verify the placeholders, or other UI aspects of the feature. + +## Structure + +Files: + +- `tds_reference.json` - Block list to be used when running the Click to Load tests. +- `config_reference.json` - Configuration to be used when running the Click to Load tests. +- `surrogates_reference.txt` - Surrogate script configuration to be used when running the Click to Load tests. +- `tests.json` - The Click to Load tests. + +Test case fields: + +- `siteUrl` - string - The currently loaded website's URL (as seen in the URL bar). +- `requestUrl` - string - The URL of the request being made. +- `userUnblockedRuleActions` - string[] - Array of Click to Load rule action that the user has unblocked for the page. +- `expectedOutcome` - "block", "redirect" or "ignore" - how request is expected to be handled ('redirect' means that surrogate was loaded instead of the original request). + +## Pseudo-code implementation + +``` +loadReferenceConfig('config_reference.json') +loadReferenceBlocklist(tds_reference.json') + +// Find the list of supported Click to Load rule actions. +$supportedRuleActions = [] +if $config.features.clickToPlay.state == enabled: + for $entity, $entity_settings in $config.features.clickToPlay.settings: + if $entity_settings.state == enabled: + for $ruleAction in $entity_settings.ruleActions: + $supportedRuleActions.push($ruleAction) + +for $testSet in test.json + for $test in $testSet + if $test.exceptPlatforms includes 'current-platform' + skip + + // Prevent user unblocked content from being blocked. + $actions = $supportedRuleActions.copy() + for $action in $test.userUnblockedRuleActions: + $actions.remove($action) + + // Prevent first-party blocking. + $entity = findParentEntity($test.siteUrl) + if $config.features.clickToPlay.settings[$entity]: + for $action in $config.features.clickToPlay.settings[$entity].ruleActions: + $actions.remove($action) + + // Prevent blocking Click to Load content if feature is disabled for tab. + if !checkFeatureEnabled($test.siteUrl, "clickToPlay"): + $actions = [] + + // Check the expected matching outcome is correct for the test request. + $result = findMatch($test.siteUrl, $test.requestUrl, $actions) + expect($action).toBe($test.expectedOutcome) +``` diff --git a/click-to-load/config_reference.json b/click-to-load/config_reference.json new file mode 100644 index 0000000..9654f54 --- /dev/null +++ b/click-to-load/config_reference.json @@ -0,0 +1,22 @@ +{ + "readme": "Test configuration for the Click to Load feature.", + "features": { + "clickToPlay": { + "state": "enabled", + "exceptions": [{ + "domain": "allowed.example", + "reason": "A really good reason" + }], + "settings": { + "Facebook": { + "state": "enabled", + "ruleActions": ["block-ctl-fb", "block-ctl-fb2"] + } + } + }, + "contentBlocking": { + "state": "enabled" + } + }, + "version": 1676030961458 +} diff --git a/click-to-load/surrogates_reference.txt b/click-to-load/surrogates_reference.txt new file mode 100644 index 0000000..1ee0da8 --- /dev/null +++ b/click-to-load/surrogates_reference.txt @@ -0,0 +1,2 @@ +facebook.net/sdk.js application/javascript +() => (); diff --git a/click-to-load/tds_reference.json b/click-to-load/tds_reference.json new file mode 100644 index 0000000..8bc29cc --- /dev/null +++ b/click-to-load/tds_reference.json @@ -0,0 +1,69 @@ +{ + "trackers": { + "facebook.com": { + "domain": "facebook.com", + "default": "block", + "owner": { + "name": "Facebook", + "displayName": "Facebook" + } + }, + "facebook.net": { + "domain": "facebook.net", + "default": "ignore", + "owner": { + "name": "Facebook", + "displayName": "Facebook" + }, + "rules": [ + { + "rule": "facebook\\.net/first-tracker", + "action": "block-ctl-fb" + }, + { + "rule": "facebook\\.net/different-tracker", + "action": "block-ctl-fb2" + }, + { + "rule": "facebook\\.net/unknown-tracker", + "action": "block-ctl-unknown" + }, + { + "rule": "facebook\\.net/script\\.js", + "surrogate": "sdk.js", + "action": "block-ctl-fb" + } + ] + }, + "tracker.example": { + "domain": "tracker.example", + "default": "block", + "owner": { + "name": "Trackers Incorporated", + "displayName": "Trackers Inc." + } + } + }, + "entities": { + "Facebook": { + "domains": [ + "facebook.com", + "facebook.net" + ], + "displayName": "Facebook" + }, + "Trackers Incorporated": { + "domains": [ + "trackers.example" + ], + "displayName": "Trackers Inc." + } + }, + "domains": { + "facebook.com": "Facebook", + "facebook.net": "Facebook", + "tracker.example": "Trackers Incorporated" + }, + "cnames": { + } +} diff --git a/click-to-load/tests.json b/click-to-load/tests.json new file mode 100644 index 0000000..4c45a53 --- /dev/null +++ b/click-to-load/tests.json @@ -0,0 +1,104 @@ +{ + "clickToLoadRequestBlocking": { + "name": "Click to Load request blocking", + "desc": "Tests to verify that Click to Load requests are being blocked correctly.", + "tests": [ + { + "name": "Unsupported rule actions", + "siteUrl": "https://third-party.example", + "requestUrl": "https://facebook.net/unknown-tracker", + "userUnblockedRuleActions": [], + "expectedOutcome": "ignore", + "exceptPlatforms": [] + }, + { + "name": "Blocked request, first rule action", + "siteUrl": "https://third-party.example", + "requestUrl": "https://facebook.net/first-tracker", + "userUnblockedRuleActions": [], + "expectedOutcome": "block", + "exceptPlatforms": [] + }, + { + "name": "Blocked request, second rule action", + "siteUrl": "https://third-party.example", + "requestUrl": "https://facebook.net/different-tracker", + "userUnblockedRuleActions": [], + "expectedOutcome": "block", + "exceptPlatforms": [] + }, + { + "name": "Surrogate script redirection", + "siteUrl": "https://third-party.example", + "requestUrl": "https://facebook.net/script.js", + "userUnblockedRuleActions": [], + "expectedOutcome": "redirect", + "exceptPlatforms": [] + }, + { + "name": "First party request", + "siteUrl": "https://facebook.com", + "requestUrl": "https://facebook.net/first-tracker", + "userUnblockedRuleActions": [], + "expectedOutcome": "ignore", + "exceptPlatforms": [] + }, + { + "name": "Disabled rule action", + "siteUrl": "https://third-party.example", + "requestUrl": "https://facebook.net/first-tracker", + "userUnblockedRuleActions": ["block-ctl-fb"], + "expectedOutcome": "ignore", + "exceptPlatforms": [] + }, + { + "name": "Different disabled rule action", + "siteUrl": "https://third-party.example", + "requestUrl": "https://facebook.net/different-tracker", + "userUnblockedRuleActions": ["block-ctl-fb2"], + "expectedOutcome": "ignore", + "exceptPlatforms": [] + }, + { + "name": "Unrelated disabled rule action", + "siteUrl": "https://third-party.example", + "requestUrl": "https://facebook.net/first-tracker", + "userUnblockedRuleActions": ["block-ctl-fb2"], + "expectedOutcome": "block", + "exceptPlatforms": [] + }, + { + "name": "Surrogate script, disabled rule action", + "siteUrl": "https://third-party.example", + "requestUrl": "https://facebook.net/script.js", + "userUnblockedRuleActions": ["block-ctl-fb"], + "expectedOutcome": "ignore", + "exceptPlatforms": [] + }, + { + "name": "Domain exception", + "siteUrl": "https://allowed.example", + "requestUrl": "https://facebook.net/first-tracker", + "userUnblockedRuleActions": [], + "expectedOutcome": "ignore", + "exceptPlatforms": [] + }, + { + "name": "Two disabled rule actions - Part 1", + "siteUrl": "https://third-party.example", + "requestUrl": "https://facebook.net/tracker-tracker", + "userUnblockedRuleActions": ["block-ctl-fb", "block-ctl-fb2"], + "expectedOutcome": "ignore", + "exceptPlatforms": [] + }, + { + "name": "Two disabled rule actions - Part 2", + "siteUrl": "https://third-party.example", + "requestUrl": "https://facebook.net/different-tracker", + "userUnblockedRuleActions": ["block-ctl-fb", "block-ctl-fb2"], + "expectedOutcome": "ignore", + "exceptPlatforms": [] + } + ] + } +}