summaryrefslogtreecommitdiffstats
path: root/src/tests/tests/yellowlist.js
diff options
context:
space:
mode:
Diffstat (limited to 'src/tests/tests/yellowlist.js')
-rw-r--r--src/tests/tests/yellowlist.js424
1 files changed, 424 insertions, 0 deletions
diff --git a/src/tests/tests/yellowlist.js b/src/tests/tests/yellowlist.js
new file mode 100644
index 0000000..43fa869
--- /dev/null
+++ b/src/tests/tests/yellowlist.js
@@ -0,0 +1,424 @@
+/* globals badger:false */
+
+(function () {
+
+function get_ylist() {
+ return badger.storage.getStore('cookieblock_list').getItemClones();
+}
+
+let constants = require('constants');
+
+// fake server to simulate XMLHttpRequests
+let server;
+
+QUnit.module("Yellowlist", (hooks) => {
+ hooks.before((/*assert*/) => {
+ server = sinon.fakeServer.create({
+ respondImmediately: true
+ });
+ });
+
+ hooks.after((/*assert*/) => {
+ server.restore();
+ });
+
+ QUnit.test("Updating to a valid list", (assert) => {
+ let done = assert.async();
+ assert.expect(3);
+
+ let ylist = get_ylist();
+ assert.ok(!!Object.keys(ylist).length, "yellowlist is not empty");
+
+ // remove a domain
+ let removed_domain = Object.keys(ylist)[0];
+ delete ylist[removed_domain];
+
+ // add a domain
+ const NEW_YLIST_DOMAIN = "widgets.example.com";
+ ylist[NEW_YLIST_DOMAIN] = true;
+
+ // respond with the modified list
+ server.respondWith("GET", constants.YELLOWLIST_URL,
+ [200, {}, Object.keys(ylist).join("\n")]);
+
+ badger.updateYellowlist(function (err) {
+ assert.notOk(err, "callback status indicates success");
+ assert.deepEqual(get_ylist(), ylist, "list got updated");
+ done();
+ });
+ });
+
+ QUnit.test("Updating receives a blank response", (assert) => {
+ let done = assert.async();
+ assert.expect(3);
+
+ let ylist = get_ylist();
+ assert.ok(!!Object.keys(ylist).length, "yellowlist is not empty");
+
+ // respond with no content
+ server.respondWith("GET", constants.YELLOWLIST_URL,
+ [200, {}, ""]);
+
+ badger.updateYellowlist(function (err) {
+ assert.ok(err, "callback status indicates failure");
+ assert.deepEqual(get_ylist(), ylist, "list did not get updated");
+ done();
+ });
+ });
+
+ QUnit.test("Updating receives an invalid response", (assert) => {
+ let BAD_RESPONSES = [
+ "page not found",
+ "page\nnot\nfound",
+ "pagenotfound",
+ "eff.org\n...\n",
+ "...eff.org...",
+ "<html><body>eff.org</body></html>",
+ ];
+
+ let done = assert.async(BAD_RESPONSES.length);
+ assert.expect(1 + (2 * BAD_RESPONSES.length));
+
+ let ylist = get_ylist();
+ assert.ok(!!Object.keys(ylist).length, "yellowlist is not empty");
+
+ BAD_RESPONSES.forEach(response => {
+ // respond with stuff that may look like the yellowlist but is not
+ server.respondWith("GET", constants.YELLOWLIST_URL,
+ [200, {}, response]);
+
+ badger.updateYellowlist(function (err) {
+ assert.ok(err,
+ "callback status indicates failure for " + JSON.stringify(response));
+ assert.deepEqual(get_ylist(), ylist,
+ "list did not get updated for " + JSON.stringify(response));
+ done();
+ });
+ });
+ });
+
+ QUnit.test("Updating gets a server error", (assert) => {
+ let done = assert.async();
+ assert.expect(1);
+
+ // respond with a 404 error
+ server.respondWith("GET", constants.YELLOWLIST_URL,
+ [404, {}, "page not found"]);
+
+ badger.updateYellowlist(function (err) {
+ assert.ok(err, "callback status indicates failure");
+ done();
+ });
+ });
+
+ QUnit.test("added domains get cookieblocked", (assert) => {
+ const DOMAIN = "example.com";
+
+ let done = assert.async();
+ assert.expect(2);
+
+ // mark domain for blocking
+ badger.storage.setupHeuristicAction(DOMAIN, constants.BLOCK);
+
+ // respond with this domain added
+ let ylist = get_ylist();
+ ylist[DOMAIN] = true;
+ server.respondWith("GET", constants.YELLOWLIST_URL,
+ [200, {}, Object.keys(ylist).join("\n")]);
+
+ // update yellowlist
+ badger.updateYellowlist(function (err) {
+ assert.notOk(err, "callback status indicates success");
+
+ // check that the domain got cookieblocked
+ assert.equal(
+ badger.storage.getAction(DOMAIN),
+ constants.COOKIEBLOCK,
+ "domain is marked for cookieblocking"
+ );
+
+ done();
+ });
+ });
+
+ QUnit.test("Reapplying yellowlist updates", (assert) => {
+ // these are all on the yellowlist
+ let DOMAINS = [
+ // domain, action
+ ["books.google.com", null], // null means do not record
+ ["clients6.google.com", ""],
+ ["storage.googleapis.com", constants.BLOCK],
+ ];
+
+ // set up test data
+ for (let i = 0; i < DOMAINS.length; i++) {
+ let [domain, action] = DOMAINS[i];
+ if (action !== null) {
+ // record the domain with specified action
+ badger.storage.setupHeuristicAction(domain, action);
+
+ // block the base domain
+ badger.storage.setupHeuristicAction(
+ window.getBaseDomain(domain), constants.BLOCK);
+ }
+ }
+
+ // (re)apply yellowlist updates
+ require("migrations").Migrations.reapplyYellowlist(badger);
+
+ // all test domains should be now set to "cookieblock"
+ for (let i = 0; i < DOMAINS.length; i++) {
+ let [domain,] = DOMAINS[i];
+ assert.equal(
+ badger.storage.getBestAction(domain),
+ constants.COOKIEBLOCK,
+ domain + " is cookieblocked"
+ );
+ }
+ });
+
+ QUnit.module("Removing domains", () => {
+ let TESTS = [
+ {
+ name: "Basic scenario",
+ domains: {
+ 'example.com': {
+ yellowlist: true,
+ remove: true,
+ initial: constants.COOKIEBLOCK,
+ expected: constants.BLOCK,
+ expectedBest: constants.BLOCK
+ },
+ }
+ },
+
+ {
+ name: "Parent is on yellowlist",
+ domains: {
+ 'widgets.example.com': {
+ yellowlist: true,
+ initial: constants.COOKIEBLOCK
+ },
+ 'cdn.widgets.example.com': {
+ yellowlist: true,
+ remove: true,
+ initial: constants.COOKIEBLOCK,
+ expected: constants.COOKIEBLOCK,
+ expectedBest: constants.COOKIEBLOCK
+ },
+ }
+ },
+
+ // scenario from https://github.com/EFForg/privacybadger/issues/1474
+ {
+ name: "Parent is on yellowlist and is a PSL TLD (not in action map)",
+ domains: {
+ 'googleapis.com': {
+ yellowlist: true,
+ expected: constants.NO_TRACKING,
+ expectedBest: constants.NO_TRACKING,
+ },
+ 'ajax.googleapis.com': {
+ yellowlist: true,
+ remove: true,
+ initial: constants.COOKIEBLOCK,
+ expected: constants.COOKIEBLOCK,
+ expectedBest: constants.COOKIEBLOCK
+ },
+ }
+ },
+
+ {
+ name: "Child is on yellowlist",
+ domains: {
+ 'widgets.example.com': {
+ yellowlist: true,
+ remove: true,
+ initial: constants.COOKIEBLOCK,
+ expected: constants.BLOCK,
+ expectedBest: constants.BLOCK
+ },
+ 'cdn.widgets.example.com': {
+ yellowlist: true,
+ expected: constants.COOKIEBLOCK,
+ expectedBest: constants.COOKIEBLOCK
+ },
+ }
+ },
+
+ {
+ name: "Removing parent blocks subdomains",
+ domains: {
+ // parent domain is yellowlisted and cookieblocked
+ 'example.com': {
+ yellowlist: true,
+ remove: true,
+ initial: constants.COOKIEBLOCK,
+ expected: constants.BLOCK,
+ expectedBest: constants.BLOCK
+ },
+ // non-yellowlisted subdomain
+ 'cdn1.example.com': {
+ initial: constants.COOKIEBLOCK,
+ expected: constants.BLOCK,
+ expectedBest: constants.BLOCK
+ },
+ // another non-yellowlisted subdomain
+ 'cdn2.example.com': {
+ initial: constants.COOKIEBLOCK,
+ expected: constants.BLOCK,
+ expectedBest: constants.BLOCK
+ },
+ }
+ },
+
+ {
+ name: "Parent is blocked",
+ domains: {
+ 'example.com': {
+ initial: constants.BLOCK,
+ },
+ // removing from yellowlist will get this blocked
+ 'www.example.com': {
+ yellowlist: true,
+ remove: true,
+ initial: constants.COOKIEBLOCK,
+ expected: constants.BLOCK,
+ expectedBest: constants.BLOCK
+ },
+ // removing from yellowlist will get this blocked
+ 's-static.ak.example.com': {
+ yellowlist: true,
+ remove: true,
+ initial: constants.COOKIEBLOCK,
+ expected: constants.BLOCK,
+ expectedBest: constants.BLOCK
+ },
+ // yellowlisted and cookieblocked, should stay the same
+ 'video.example.com': {
+ yellowlist: true,
+ initial: constants.COOKIEBLOCK,
+ expected: constants.COOKIEBLOCK,
+ expectedBest: constants.COOKIEBLOCK
+ },
+ // non-tracking, should stay the same
+ 'ampcid.example.com': {
+ initial: "",
+ expected: constants.NO_TRACKING,
+ expectedBest: constants.BLOCK
+ },
+ }
+ },
+
+ // scenario from https://github.com/EFForg/privacybadger/issues/1474:
+ // using endsWith() and removing "" blocked all domains in action map
+ // that were also on the yellowlist, regardless of their status
+ {
+ name: "Removing blank domain does not block entire yellowlist",
+ domains: {
+ '': {
+ yellowlist: true,
+ remove: true
+ },
+ // on yellowlist and in action map as non-tracking
+ 'avatars0.example.com': {
+ yellowlist: true,
+ initial: "",
+ expected: constants.NO_TRACKING,
+ expectedBest: constants.NO_TRACKING
+ },
+ // on yellowlist and in action map but not yet blocked
+ 'api.example.net': {
+ yellowlist: true,
+ initial: constants.ALLOW,
+ expected: constants.ALLOW,
+ expectedBest: constants.ALLOW
+ }
+ }
+ }
+ ];
+
+ QUnit.test("googleapis.com is still a PSL TLD", (assert) => {
+ assert.notEqual(
+ window.getBaseDomain("ajax.googleapis.com"),
+ "googleapis.com",
+ "PSL yellowlist test depends on googleapis.com remaining a PSL TLD"
+ );
+ });
+
+ TESTS.forEach(test => {
+ QUnit.test(test.name, (assert) => {
+
+ let done = assert.async();
+
+ // to get num. of assertions, tally the expected/expectedBest props,
+ // and add one for the yellowlist update assertion
+ assert.expect(1 + Object.keys(test.domains).reduce((memo, domain) => {
+ let data = test.domains[domain];
+ if (data.hasOwnProperty('expected')) {
+ memo++;
+ }
+ if (data.hasOwnProperty('expectedBest')) {
+ memo++;
+ }
+ return memo;
+ }, 0));
+
+ let ylistStorage = badger.storage.getStore('cookieblock_list');
+
+ // set up cookieblocking
+ for (let domain in test.domains) {
+ let conf = test.domains[domain];
+ if (conf.yellowlist) {
+ ylistStorage.setItem(domain, true);
+ }
+ if (conf.hasOwnProperty("initial")) {
+ badger.storage.setupHeuristicAction(domain, conf.initial);
+ }
+ }
+
+ // update the yellowlist making sure removed domains aren't on it
+ const ylist = ylistStorage.getItemClones();
+ for (let domain in test.domains) {
+ if (test.domains[domain].remove) {
+ delete ylist[domain];
+ }
+ }
+ server.respondWith("GET", constants.YELLOWLIST_URL,
+ [200, {}, Object.keys(ylist).join("\n")]);
+
+ badger.updateYellowlist(err => {
+ assert.notOk(err, "callback status indicates success");
+
+ for (let domain in test.domains) {
+ let expected, data = test.domains[domain];
+
+ if (data.hasOwnProperty('expected')) {
+ expected = data.expected;
+ assert.equal(
+ badger.storage.getAction(domain),
+ expected,
+ `action on ${domain} should be "${expected}"`
+ );
+ }
+
+ if (data.hasOwnProperty('expectedBest')) {
+ expected = data.expectedBest;
+ assert.equal(
+ badger.storage.getBestAction(domain),
+ expected,
+ `best action for ${domain} should be "${expected}"`
+ );
+ }
+ }
+
+ done();
+ });
+
+ });
+ });
+ });
+
+});
+
+}());