pdf.js/test/chromium/test-telemetry.js

419 lines
13 KiB
JavaScript
Raw Normal View History

#!/usr/bin/env node
/* Copyright 2016 Mozilla Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* eslint-disable object-shorthand */
'use strict';
var assert = require('assert');
var fs = require('fs');
var vm = require('vm');
var SRC_DIR = __dirname + '/../../';
var telemetryJsPath = 'extensions/chromium/telemetry.js';
var telemetryJsSource = fs.readFileSync(SRC_DIR + telemetryJsPath);
var telemetryScript = new vm.Script(telemetryJsSource, {
filename: telemetryJsPath,
displayErrors: true,
});
var LOG_URL = /LOG_URL = '([^']+)'/.exec(telemetryJsSource)[1];
// Create a minimal extension global that mocks the extension environment that
// is used by telemetry.js
function createExtensionGlobal() {
var window = {};
// Whenever a "request" was made, the extra headers are appended to this list.
var test_requests = window.test_requests = [];
// Extension API mocks.
window.window = window;
window.chrome = {};
window.chrome.extension = {};
window.chrome.extension.inIncognitoContext = false;
window.chrome.runtime = {};
window.chrome.runtime.id = 'oemmndcbldboiebfnladdacbdfmadadm';
window.chrome.runtime.getManifest = function() {
Fix inconsistent spacing and trailing commas in objects in `test/` files, so we can enable the `comma-dangle` and `object-curly-spacing` ESLint rules later on http://eslint.org/docs/rules/comma-dangle http://eslint.org/docs/rules/object-curly-spacing Given that we currently have quite inconsistent object formatting, fixing this in *one* big patch probably wouldn't be feasible (since I cannot imagine anyone wanting to review that); hence I've opted to try and do this piecewise instead. Please note: This patch was created automatically, using the ESLint `--fix` command line option. In a couple of places this caused lines to become too long, and I've fixed those manually; please refer to the interdiff below for the only hand-edits in this patch. ```diff diff --git a/test/chromium/test-telemetry.js b/test/chromium/test-telemetry.js index cc412a31..2e5bdfa1 100755 --- a/test/chromium/test-telemetry.js +++ b/test/chromium/test-telemetry.js @@ -324,7 +324,7 @@ var tests = [ var window = createExtensionGlobal(); telemetryScript.runInNewContext(window); window.chrome.runtime.getManifest = function() { - return { version: '1.0.1', }; + return { version: '1.0.1', }; }; window.Date.test_now_value += 12 * 36E5; telemetryScript.runInNewContext(window); diff --git a/test/unit/api_spec.js b/test/unit/api_spec.js index 1f00747a..f22988e7 100644 --- a/test/unit/api_spec.js +++ b/test/unit/api_spec.js @@ -503,8 +503,9 @@ describe('api', function() { it('gets destinations, from /Dests dictionary', function(done) { var promise = doc.getDestinations(); promise.then(function(data) { - expect(data).toEqual({ chapter1: [{ gen: 0, num: 17, }, { name: 'XYZ', }, - 0, 841.89, null], }); + expect(data).toEqual({ + chapter1: [{ gen: 0, num: 17, }, { name: 'XYZ', }, 0, 841.89, null], + }); done(); }).catch(function (reason) { done.fail(reason); diff --git a/test/unit/function_spec.js b/test/unit/function_spec.js index 66441212..62127eb9 100644 --- a/test/unit/function_spec.js +++ b/test/unit/function_spec.js @@ -492,9 +492,11 @@ describe('function', function() { it('check compiled mul', function() { check([0.25, 0.5, 'mul'], [], [0, 1], [{ input: [], output: [0.125], }]); check([0, 'mul'], [0, 1], [0, 1], [{ input: [0.25], output: [0], }]); - check([0.5, 'mul'], [0, 1], [0, 1], [{ input: [0.25], output: [0.125], }]); + check([0.5, 'mul'], [0, 1], [0, 1], + [{ input: [0.25], output: [0.125], }]); check([1, 'mul'], [0, 1], [0, 1], [{ input: [0.25], output: [0.25], }]); - check([0, 'exch', 'mul'], [0, 1], [0, 1], [{ input: [0.25], output: [0], }]); + check([0, 'exch', 'mul'], [0, 1], [0, 1], + [{ input: [0.25], output: [0], }]); check([0.5, 'exch', 'mul'], [0, 1], [0, 1], [{ input: [0.25], output: [0.125], }]); check([1, 'exch', 'mul'], [0, 1], [0, 1], ```
2017-06-02 19:55:01 +09:00
return { version: '1.0.0', };
};
function createStorageAPI() {
var storageArea = {};
storageArea.get = function(key, callback) {
assert.equal(key, 'disableTelemetry');
// chrome.storage.*. is async, but we make it synchronous to ease testing.
callback(storageArea.mock_data);
};
return storageArea;
}
window.chrome.storage = {};
window.chrome.storage.managed = createStorageAPI();
window.chrome.storage.local = createStorageAPI();
window.chrome.storage.sync = createStorageAPI();
// Other DOM.
window.navigator = {};
window.navigator.onLine = true;
window.navigator.userAgent =
'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) ' +
'Chrome/50.0.2661.94 Safari/537.36';
window.localStorage = {};
var getRandomValues_state = 0;
window.crypto = {};
window.crypto.getRandomValues = function(buf) {
var state = getRandomValues_state++;
for (var i = 0; i < buf.length; ++i) {
// Totally random byte ;)
buf[i] = 0x42 + state;
}
return buf;
};
// Network-related mocks.
window.Request = {};
window.Request.prototype = {
get mode() {
throw new TypeError('Illegal invocation');
},
};
window.fetch = function(url, options) {
assert.equal(url, LOG_URL);
assert.equal(options.method, 'POST');
assert.equal(options.mode, 'cors');
assert.ok(!options.body);
test_requests.push(options.headers);
};
window.Headers = function(headers) {
headers = JSON.parse(JSON.stringify(headers)); // Clone.
Object.keys(headers).forEach(function(k) {
headers[k] = String(headers[k]);
});
return headers;
};
window.XMLHttpRequest = function() {
var invoked = {
open: false,
send: false,
};
var headers = {};
return {
open: function(method, url) {
assert.equal(invoked.open, false);
invoked.open = true;
assert.equal(method, 'POST');
assert.equal(url, LOG_URL);
},
setRequestHeader: function(k, v) {
assert.equal(invoked.open, true);
headers[k] = String(v);
},
send: function(body) {
assert.equal(invoked.open, true);
assert.equal(invoked.send, false);
invoked.send = true;
assert.ok(!body);
test_requests.push(headers);
},
};
};
// Time-related logic.
var timers = [];
window.setInterval = function(callback, ms) {
assert.equal(typeof callback, 'function');
timers.push(callback);
};
window.Date = {
test_now_value: Date.now(),
now: function() {
return window.Date.test_now_value;
},
};
window.test_fireTimers = function() {
assert.ok(timers.length);
timers.forEach(function(timer) {
timer();
});
};
return window;
}
// Simulate an update of the browser.
function updateBrowser(window) {
window.navigator.userAgent =
window.navigator.userAgent.replace(/Chrome\/(\d+)/, function(_, v) {
return 'Chrome/' + (parseInt(v) + 1);
});
}
var tests = [
function test_first_run() {
// Default settings, run extension for the first time.
var window = createExtensionGlobal();
telemetryScript.runInNewContext(window);
assert.deepEqual(window.test_requests, [{
'Deduplication-Id': '4242424242',
'Extension-Version': '1.0.0',
}]);
},
function test_first_run_incognito() {
// The extension should not send any requests when in incognito mode.
var window = createExtensionGlobal();
window.chrome.extension.inIncognitoContext = true;
telemetryScript.runInNewContext(window);
assert.deepEqual(window.test_requests, []);
},
function test_storage_managed_unavailable() {
var window = createExtensionGlobal();
delete window.chrome.storage.managed;
telemetryScript.runInNewContext(window);
assert.deepEqual(window.test_requests, [{
'Deduplication-Id': '4242424242',
'Extension-Version': '1.0.0',
}]);
},
function test_managed_pref() {
var window = createExtensionGlobal();
window.chrome.storage.managed.mock_data = {
disableTelemetry: true,
};
telemetryScript.runInNewContext(window);
assert.deepEqual(window.test_requests, []);
},
function test_local_pref() {
var window = createExtensionGlobal();
window.chrome.storage.local.mock_data = {
disableTelemetry: true,
};
telemetryScript.runInNewContext(window);
assert.deepEqual(window.test_requests, []);
},
function test_managed_pref_is_overridden() {
var window = createExtensionGlobal();
window.chrome.storage.managed.mock_data = {
disableTelemetry: true,
};
window.chrome.storage.sync.mock_data = {
disableTelemetry: false,
};
telemetryScript.runInNewContext(window);
assert.deepEqual(window.test_requests, [{
'Deduplication-Id': '4242424242',
'Extension-Version': '1.0.0',
}]);
},
function test_run_extension_again() {
var window = createExtensionGlobal();
telemetryScript.runInNewContext(window);
telemetryScript.runInNewContext(window);
// Only one request should be sent because of rate-limiting.
assert.deepEqual(window.test_requests, [{
'Deduplication-Id': '4242424242',
'Extension-Version': '1.0.0',
}]);
// Simulate that quite some hours passed, but it's still rate-limited.
window.Date.test_now_value += 11 * 36E5;
telemetryScript.runInNewContext(window);
// Only one request should be sent because of rate-limiting.
assert.deepEqual(window.test_requests, [{
'Deduplication-Id': '4242424242',
'Extension-Version': '1.0.0',
}]);
// Another hour passes and the request should not be rate-limited any more.
window.Date.test_now_value += 1 * 36E5;
telemetryScript.runInNewContext(window);
assert.deepEqual(window.test_requests, [{
'Deduplication-Id': '4242424242',
'Extension-Version': '1.0.0',
}, {
'Deduplication-Id': '4242424242',
'Extension-Version': '1.0.0',
}]);
},
function test_running_for_a_while() {
var window = createExtensionGlobal();
telemetryScript.runInNewContext(window);
assert.deepEqual(window.test_requests, [{
'Deduplication-Id': '4242424242',
'Extension-Version': '1.0.0',
}]);
// Simulate that the timer fired 11 hours since the last ping. The request
// should still be rate-limited.
window.Date.test_now_value += 11 * 36E5;
window.test_fireTimers();
assert.deepEqual(window.test_requests, [{
'Deduplication-Id': '4242424242',
'Extension-Version': '1.0.0',
}]);
// Another hour passes and the request should not be rate-limited any more.
window.Date.test_now_value += 1 * 36E5;
window.test_fireTimers();
assert.deepEqual(window.test_requests, [{
'Deduplication-Id': '4242424242',
'Extension-Version': '1.0.0',
}, {
'Deduplication-Id': '4242424242',
'Extension-Version': '1.0.0',
}]);
},
function test_browser_update() {
var window = createExtensionGlobal();
telemetryScript.runInNewContext(window);
updateBrowser(window);
telemetryScript.runInNewContext(window);
assert.deepEqual(window.test_requests, [{
'Deduplication-Id': '4242424242',
'Extension-Version': '1.0.0',
}, {
// Generate a new ID for better privacy.
'Deduplication-Id': '4343434343',
'Extension-Version': '1.0.0',
}]);
},
function test_browser_update_between_pref_toggle() {
var window = createExtensionGlobal();
telemetryScript.runInNewContext(window);
window.chrome.storage.local.mock_data = {
disableTelemetry: true,
};
updateBrowser(window);
telemetryScript.runInNewContext(window);
window.chrome.storage.local.mock_data = {
disableTelemetry: false,
};
telemetryScript.runInNewContext(window);
assert.deepEqual(window.test_requests, [{
'Deduplication-Id': '4242424242',
'Extension-Version': '1.0.0',
}, {
// Generate a new ID for better privacy, even if the update happened
// while telemetry was disabled.
'Deduplication-Id': '4343434343',
'Extension-Version': '1.0.0',
}]);
},
function test_extension_update() {
var window = createExtensionGlobal();
telemetryScript.runInNewContext(window);
window.chrome.runtime.getManifest = function() {
Fix inconsistent spacing and trailing commas in objects in `test/` files, so we can enable the `comma-dangle` and `object-curly-spacing` ESLint rules later on http://eslint.org/docs/rules/comma-dangle http://eslint.org/docs/rules/object-curly-spacing Given that we currently have quite inconsistent object formatting, fixing this in *one* big patch probably wouldn't be feasible (since I cannot imagine anyone wanting to review that); hence I've opted to try and do this piecewise instead. Please note: This patch was created automatically, using the ESLint `--fix` command line option. In a couple of places this caused lines to become too long, and I've fixed those manually; please refer to the interdiff below for the only hand-edits in this patch. ```diff diff --git a/test/chromium/test-telemetry.js b/test/chromium/test-telemetry.js index cc412a31..2e5bdfa1 100755 --- a/test/chromium/test-telemetry.js +++ b/test/chromium/test-telemetry.js @@ -324,7 +324,7 @@ var tests = [ var window = createExtensionGlobal(); telemetryScript.runInNewContext(window); window.chrome.runtime.getManifest = function() { - return { version: '1.0.1', }; + return { version: '1.0.1', }; }; window.Date.test_now_value += 12 * 36E5; telemetryScript.runInNewContext(window); diff --git a/test/unit/api_spec.js b/test/unit/api_spec.js index 1f00747a..f22988e7 100644 --- a/test/unit/api_spec.js +++ b/test/unit/api_spec.js @@ -503,8 +503,9 @@ describe('api', function() { it('gets destinations, from /Dests dictionary', function(done) { var promise = doc.getDestinations(); promise.then(function(data) { - expect(data).toEqual({ chapter1: [{ gen: 0, num: 17, }, { name: 'XYZ', }, - 0, 841.89, null], }); + expect(data).toEqual({ + chapter1: [{ gen: 0, num: 17, }, { name: 'XYZ', }, 0, 841.89, null], + }); done(); }).catch(function (reason) { done.fail(reason); diff --git a/test/unit/function_spec.js b/test/unit/function_spec.js index 66441212..62127eb9 100644 --- a/test/unit/function_spec.js +++ b/test/unit/function_spec.js @@ -492,9 +492,11 @@ describe('function', function() { it('check compiled mul', function() { check([0.25, 0.5, 'mul'], [], [0, 1], [{ input: [], output: [0.125], }]); check([0, 'mul'], [0, 1], [0, 1], [{ input: [0.25], output: [0], }]); - check([0.5, 'mul'], [0, 1], [0, 1], [{ input: [0.25], output: [0.125], }]); + check([0.5, 'mul'], [0, 1], [0, 1], + [{ input: [0.25], output: [0.125], }]); check([1, 'mul'], [0, 1], [0, 1], [{ input: [0.25], output: [0.25], }]); - check([0, 'exch', 'mul'], [0, 1], [0, 1], [{ input: [0.25], output: [0], }]); + check([0, 'exch', 'mul'], [0, 1], [0, 1], + [{ input: [0.25], output: [0], }]); check([0.5, 'exch', 'mul'], [0, 1], [0, 1], [{ input: [0.25], output: [0.125], }]); check([1, 'exch', 'mul'], [0, 1], [0, 1], ```
2017-06-02 19:55:01 +09:00
return { version: '1.0.1', };
};
window.Date.test_now_value += 12 * 36E5;
telemetryScript.runInNewContext(window);
assert.deepEqual(window.test_requests, [{
'Deduplication-Id': '4242424242',
'Extension-Version': '1.0.0',
}, {
// The ID did not change because the browser version did not change.
'Deduplication-Id': '4242424242',
'Extension-Version': '1.0.1',
}]);
},
function test_unofficial_build() {
var window = createExtensionGlobal();
var didWarn = false;
window.console = {};
window.console.warn = function() {
didWarn = true;
};
window.chrome.runtime.id = 'abcdefghijklmnopabcdefghijklmnop';
telemetryScript.runInNewContext(window);
assert.deepEqual(window.test_requests, []);
assert.ok(didWarn);
},
function test_fetch_is_supported() {
var window = createExtensionGlobal();
// XMLHttpRequest should not be called when fetch is available. So removing
// the XMLHttpRequest API should not change behavior.
delete window.XMLHttpRequest;
telemetryScript.runInNewContext(window);
assert.deepEqual(window.test_requests, [{
'Deduplication-Id': '4242424242',
'Extension-Version': '1.0.0',
}]);
},
function test_fetch_not_supported() {
var window = createExtensionGlobal();
delete window.fetch;
delete window.Request;
delete window.Headers;
telemetryScript.runInNewContext(window);
assert.deepEqual(window.test_requests, [{
'Deduplication-Id': '4242424242',
'Extension-Version': '1.0.0',
}]);
},
function test_fetch_mode_not_supported() {
var window = createExtensionGlobal();
delete window.Request.prototype.mode;
window.fetch = function() {
throw new Error('Unexpected call to fetch!');
};
telemetryScript.runInNewContext(window);
assert.deepEqual(window.test_requests, [{
'Deduplication-Id': '4242424242',
'Extension-Version': '1.0.0',
}]);
},
function test_network_offline() {
var window = createExtensionGlobal();
// Simulate that the network is down for sure.
window.navigator.onLine = false;
telemetryScript.runInNewContext(window);
assert.deepEqual(window.test_requests, []);
// Simulate that the network might be up.
window.navigator.onLine = true;
telemetryScript.runInNewContext(window);
assert.deepEqual(window.test_requests, [{
'Deduplication-Id': '4242424242',
'Extension-Version': '1.0.0',
}]);
},
];
var test_i = 0;
(function next() {
var test = tests[test_i++];
if (!test) {
console.log('All tests completed.');
return;
}
console.log('Running test ' + test_i + '/' + tests.length + ': ' + test.name);
test();
process.nextTick(next);
})();