From 92bc667f4040702d1c648ae9fcd976b16fecbfb0 Mon Sep 17 00:00:00 2001 From: Mark Finkle Date: Tue, 11 Nov 2014 15:04:01 -0500 Subject: [PATCH] Bug 1063831 - Add simple tests for tracking protection r=margaret --- mobile/android/base/tests/robocop.ini | 1 + .../base/tests/testTrackingProtection.java | 63 ++++++++ .../base/tests/testTrackingProtection.js | 137 ++++++++++++++++++ mobile/android/base/tests/tracking_bad.html | 12 ++ mobile/android/base/tests/tracking_good.html | 12 ++ 5 files changed, 225 insertions(+) create mode 100644 mobile/android/base/tests/testTrackingProtection.java create mode 100644 mobile/android/base/tests/testTrackingProtection.js create mode 100644 mobile/android/base/tests/tracking_bad.html create mode 100644 mobile/android/base/tests/tracking_good.html diff --git a/mobile/android/base/tests/robocop.ini b/mobile/android/base/tests/robocop.ini index 09983579c48b..c68f7f40d5e5 100644 --- a/mobile/android/base/tests/robocop.ini +++ b/mobile/android/base/tests/robocop.ini @@ -114,6 +114,7 @@ skip-if = android_version == "10" [testRestrictedProfiles] [testSharedPreferences] [testSimpleDiscovery] +[testTrackingProtection] [testUITelemetry] [testVideoControls] # disabled on Android 2.3 due to video playback issues; bug 1088038 diff --git a/mobile/android/base/tests/testTrackingProtection.java b/mobile/android/base/tests/testTrackingProtection.java new file mode 100644 index 000000000000..8d781fe1cda0 --- /dev/null +++ b/mobile/android/base/tests/testTrackingProtection.java @@ -0,0 +1,63 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +package org.mozilla.gecko.tests; + +import static org.mozilla.gecko.tests.helpers.AssertionHelper.fFail; + +import org.mozilla.gecko.EventDispatcher; +import org.mozilla.gecko.GeckoAppShell; +import org.mozilla.gecko.GeckoEvent; +import org.mozilla.gecko.util.GeckoEventListener; + +import org.json.JSONException; +import org.json.JSONObject; + +public class testTrackingProtection extends JavascriptTest implements GeckoEventListener { + private String mLastTracking; + + public testTrackingProtection() { + super("testTrackingProtection.js"); + } + + @Override + public void handleMessage(String event, final JSONObject message) { + if (event.equals("Content:SecurityChange")) { + try { + JSONObject identity = message.getJSONObject("identity"); + JSONObject mode = identity.getJSONObject("mode"); + mLastTracking = mode.getString("tracking"); + mAsserter.dumpLog("Security change (tracking): " + mLastTracking); + } catch (Exception e) { + fFail("Can't extract tracking state from JSON"); + } + } + + if (event.equals("Test:Expected")) { + try { + String expected = message.getString("expected"); + mAsserter.is(mLastTracking, expected, "Tracking matched expectation"); + mAsserter.dumpLog("Testing (tracking): " + mLastTracking + " = " + expected); + } catch (Exception e) { + fFail("Can't extract expected state from JSON"); + } + } + } + + @Override + public void setUp() throws Exception { + super.setUp(); + + EventDispatcher.getInstance().registerGeckoThreadListener(this, "Content:SecurityChange"); + EventDispatcher.getInstance().registerGeckoThreadListener(this, "Test:Expected"); + } + + @Override + public void tearDown() throws Exception { + super.tearDown(); + + EventDispatcher.getInstance().unregisterGeckoThreadListener(this, "Content:SecurityChange"); + EventDispatcher.getInstance().unregisterGeckoThreadListener(this, "Test:Expected"); + } +} diff --git a/mobile/android/base/tests/testTrackingProtection.js b/mobile/android/base/tests/testTrackingProtection.js new file mode 100644 index 000000000000..e69bdda71c68 --- /dev/null +++ b/mobile/android/base/tests/testTrackingProtection.js @@ -0,0 +1,137 @@ +// -*- indent-tabs-mode: nil; js-indent-level: 2 -*- +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +"use strict"; + +const { classes: Cc, interfaces: Ci, utils: Cu } = Components; + +Cu.import("resource://gre/modules/XPCOMUtils.jsm"); +Cu.import("resource://gre/modules/Services.jsm"); +Cu.import("resource://gre/modules/Messaging.jsm"); + +function ok(passed, text) { + do_report_result(passed, text, Components.stack.caller, false); +} + +function promiseLoadEvent(browser, url, eventType="load") { + return new Promise((resolve, reject) => { + do_print("Wait browser event: " + eventType); + + function handle(event) { + if (event.target != browser.contentDocument || event.target.location.href == "about:blank" || (url && event.target.location.href != url)) { + do_print("Skipping spurious '" + eventType + "' event" + " for " + event.target.location.href); + return; + } + + browser.removeEventListener(eventType, handle, true); + do_print("Browser event received: " + eventType); + resolve(event); + } + + browser.addEventListener(eventType, handle, true, true); + if (url) { + browser.loadURI(url); + } + }); +} + +// Test that the Tracking Protection is active and has the correct state when +// tracking content is blocked (Bug 1063831) + +// Code is mostly stolen from: +// http://mxr.mozilla.org/mozilla-central/source/browser/base/content/test/general/browser_trackingUI.js + +var PREF = "privacy.trackingprotection.enabled"; +var TABLE = "urlclassifier.trackingTable"; + +// Update tracking database +function doUpdate() { + // Add some URLs to the tracking database (to be blocked) + var testData = "tracking.example.com/"; + var testUpdate = + "n:1000\ni:test-track-simple\nad:1\n" + + "a:524:32:" + testData.length + "\n" + + testData; + + let dbService = Cc["@mozilla.org/url-classifier/dbservice;1"].getService(Ci.nsIUrlClassifierDBService); + + return new Promise((resolve, reject) => { + let listener = { + QueryInterface: function(iid) { + if (iid.equals(Ci.nsISupports) || iid.equals(Ci.nsIUrlClassifierUpdateObserver)) + return this; + + throw Cr.NS_ERROR_NO_INTERFACE; + }, + updateUrlRequested: function(url) { }, + streamFinished: function(status) { }, + updateError: function(errorCode) { + ok(false, "Couldn't update classifier."); + resolve(); + }, + updateSuccess: function(requestedTimeout) { + resolve(); + } + }; + + dbService.beginUpdate(listener, "test-track-simple", ""); + dbService.beginStream("", ""); + dbService.updateStream(testUpdate); + dbService.finishStream(); + dbService.finishUpdate(); + }); +} + +// Track the where the tests are happening +let browser; + +add_test(function setup_browser() { + let chromeWin = Services.wm.getMostRecentWindow("navigator:browser"); + let BrowserApp = chromeWin.BrowserApp; + + do_register_cleanup(function cleanup() { + Services.prefs.clearUserPref(PREF); + Services.prefs.clearUserPref(TABLE); + BrowserApp.closeTab(BrowserApp.getTabForBrowser(browser)); + }); + + // Load a blank page + let url = "about:blank"; + browser = BrowserApp.addTab(url, { selected: true, parentId: BrowserApp.selectedTab.id }).browser; + browser.addEventListener("load", function startTests(event) { + browser.removeEventListener("load", startTests, true); + Services.tm.mainThread.dispatch(run_next_test, Ci.nsIThread.DISPATCH_NORMAL); + }, true); +}); + +add_task(function* () { + // Populate and use 'test-track-simple' for tracking protection lookups + Services.prefs.setCharPref(TABLE, "test-track-simple"); + yield doUpdate(); + + // Enable Tracking Protection + Services.prefs.setBoolPref(PREF, true); + + // Point tab to a test page NOT containing tracking elements + yield promiseLoadEvent(browser, "http://tracking.example.org/tests/robocop/tracking_good.html"); + Messaging.sendRequest({ type: "Test:Expected", expected: "unknown" }); + + // Point tab to a test page containing tracking elements + yield promiseLoadEvent(browser, "http://tracking.example.org/tests/robocop/tracking_bad.html"); + Messaging.sendRequest({ type: "Test:Expected", expected: "tracking_content_blocked" }); + + // Disable Tracking Protection + Services.prefs.setBoolPref(PREF, false); + + // Point tab to a test page containing tracking elements + yield promiseLoadEvent(browser, "http://tracking.example.org/tests/robocop/tracking_bad.html"); + Messaging.sendRequest({ type: "Test:Expected", expected: "unknown" }); + + // Point tab to a test page NOT containing tracking elements + yield promiseLoadEvent(browser, "http://tracking.example.org/tests/robocop/tracking_good.html"); + Messaging.sendRequest({ type: "Test:Expected", expected: "unknown" }); +}); + +run_next_test(); diff --git a/mobile/android/base/tests/tracking_bad.html b/mobile/android/base/tests/tracking_bad.html new file mode 100644 index 000000000000..17f0e459e3d1 --- /dev/null +++ b/mobile/android/base/tests/tracking_bad.html @@ -0,0 +1,12 @@ + + + + + + + + + + diff --git a/mobile/android/base/tests/tracking_good.html b/mobile/android/base/tests/tracking_good.html new file mode 100644 index 000000000000..8e9429acdcf9 --- /dev/null +++ b/mobile/android/base/tests/tracking_good.html @@ -0,0 +1,12 @@ + + + + + + + + + +