netwerk/test/mochitests/test_user_agent_updates.html

Wed, 31 Dec 2014 06:55:46 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:55:46 +0100
changeset 1
ca08bd8f51b2
permissions
-rw-r--r--

Added tag TORBROWSER_REPLICA for changeset 6474c204b198

michael@0 1 <!DOCTYPE HTML>
michael@0 2 <html>
michael@0 3 <!--
michael@0 4 https://bugzilla.mozilla.org/show_bug.cgi?id=897221
michael@0 5 -->
michael@0 6 <head>
michael@0 7 <title>Test for User Agent Updates</title>
michael@0 8 <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
michael@0 9 <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
michael@0 10 </head>
michael@0 11 <body>
michael@0 12 <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=897221">Mozilla Bug 897221</a>
michael@0 13 <p id="display"></p>
michael@0 14 <div id="content" style="display: none"></div>
michael@0 15 <pre id="test">
michael@0 16 <script class="testbody" type="text/javascript">
michael@0 17
michael@0 18 const PREF_APP_UPDATE_TIMERMINIMUMDELAY = "app.update.timerMinimumDelay";
michael@0 19 const PREF_UPDATES = "general.useragent.updates.";
michael@0 20 const PREF_UPDATES_ENABLED = PREF_UPDATES + "enabled";
michael@0 21 const PREF_UPDATES_URL = PREF_UPDATES + "url";
michael@0 22 const PREF_UPDATES_INTERVAL = PREF_UPDATES + "interval";
michael@0 23 const PREF_UPDATES_TIMEOUT = PREF_UPDATES + "timeout";
michael@0 24
michael@0 25 const KEY_PREFDIR = "PrefD";
michael@0 26 const KEY_APPDIR = "XCurProcD";
michael@0 27 const FILE_UPDATES = "ua-update.json";
michael@0 28
michael@0 29 const DEFAULT_UA = navigator.userAgent;
michael@0 30 const UA_OVERRIDE = "DummyUserAgent";
michael@0 31 const UA_ALT_OVERRIDE = "AltUserAgent";
michael@0 32
michael@0 33 const UA_PARTIAL_FROM = "\\wozilla"; // /\wozilla
michael@0 34 const UA_PARTIAL_SEP = "#";
michael@0 35 const UA_PARTIAL_TO = UA_OVERRIDE;
michael@0 36 const UA_PARTIAL_OVERRIDE = UA_PARTIAL_FROM + UA_PARTIAL_SEP + UA_PARTIAL_TO;
michael@0 37 const UA_PARTIAL_EXPECTED = DEFAULT_UA.replace(new RegExp(UA_PARTIAL_FROM, 'g'), UA_PARTIAL_TO);
michael@0 38
michael@0 39 function getUA(host) {
michael@0 40 var url = location.pathname;
michael@0 41 url = host + url.slice(0, url.lastIndexOf('/')) + '/user_agent.sjs';
michael@0 42
michael@0 43 var xhr = new XMLHttpRequest();
michael@0 44 xhr.open('GET', url, false); // sync request
michael@0 45 xhr.send();
michael@0 46 is(xhr.status, 200, 'request failed');
michael@0 47 is(typeof xhr.response, 'string', 'invalid response');
michael@0 48 return xhr.response;
michael@0 49 }
michael@0 50
michael@0 51 const OVERRIDES = [
michael@0 52 {
michael@0 53 domain: 'example.org',
michael@0 54 override: '%DATE%',
michael@0 55 host: 'http://example.org'
michael@0 56 },
michael@0 57 {
michael@0 58 domain: 'test1.example.org',
michael@0 59 override: '%PRODUCT%',
michael@0 60 expected: SpecialPowers.Services.appinfo.name,
michael@0 61 host: 'http://test1.example.org'
michael@0 62 },
michael@0 63 {
michael@0 64 domain: 'test2.example.org',
michael@0 65 override: '%APP_ID%',
michael@0 66 expected: SpecialPowers.Services.appinfo.ID,
michael@0 67 host: 'http://test2.example.org'
michael@0 68 },
michael@0 69 {
michael@0 70 domain: 'sub1.test1.example.org',
michael@0 71 override: '%APP_VERSION%',
michael@0 72 expected: SpecialPowers.Services.appinfo.version,
michael@0 73 host: 'http://sub1.test1.example.org'
michael@0 74 },
michael@0 75 {
michael@0 76 domain: 'sub2.test1.example.org',
michael@0 77 override: '%BUILD_ID%',
michael@0 78 expected: SpecialPowers.Services.appinfo.appBuildID,
michael@0 79 host: 'http://sub2.test1.example.org'
michael@0 80 },
michael@0 81 {
michael@0 82 domain: 'sub1.test2.example.org',
michael@0 83 override: '%OS%',
michael@0 84 expected: SpecialPowers.Services.appinfo.OS,
michael@0 85 host: 'http://sub1.test2.example.org'
michael@0 86 },
michael@0 87 {
michael@0 88 domain: 'sub2.test2.example.org',
michael@0 89 override: UA_PARTIAL_OVERRIDE,
michael@0 90 expected: UA_PARTIAL_EXPECTED,
michael@0 91 host: 'http://sub2.test2.example.org'
michael@0 92 },
michael@0 93 ];
michael@0 94
michael@0 95 function getServerURL() {
michael@0 96 var url = location.pathname;
michael@0 97 return location.origin + url.slice(0, url.lastIndexOf('/')) + '/user_agent_update.sjs?';
michael@0 98 }
michael@0 99
michael@0 100 function getUpdateURL() {
michael@0 101 var url = getServerURL();
michael@0 102 var overrides = {};
michael@0 103 overrides[location.hostname] = UA_OVERRIDE;
michael@0 104 OVERRIDES.forEach(function (val) {
michael@0 105 overrides[val.domain] = val.override;
michael@0 106 });
michael@0 107 url = url + encodeURIComponent(JSON.stringify(overrides)).replace(/%25/g, '%');
michael@0 108 return url;
michael@0 109 }
michael@0 110
michael@0 111 function testDownload(callback) {
michael@0 112 var startTime = Date.now();
michael@0 113 var url = getUpdateURL();
michael@0 114 isnot(navigator.userAgent, UA_OVERRIDE, 'UA already overridden');
michael@0 115 info('Waiting for UA update: ' + url);
michael@0 116 SpecialPowers.pushPrefEnv({
michael@0 117 set: [
michael@0 118 [PREF_UPDATES_ENABLED, true],
michael@0 119 [PREF_UPDATES_URL, url],
michael@0 120 [PREF_UPDATES_TIMEOUT, 10000],
michael@0 121 [PREF_UPDATES_INTERVAL, 1] // 1 second interval
michael@0 122 ]
michael@0 123 }, function waitForUpdate() setTimeout(function () {
michael@0 124 if (navigator.userAgent !== UA_OVERRIDE) {
michael@0 125 waitForUpdate();
michael@0 126 return;
michael@0 127 }
michael@0 128 info('Overrode navigator UA');
michael@0 129 is(getUA(location.origin), UA_OVERRIDE, 'Header UA not overridden');
michael@0 130
michael@0 131 var updateTime = parseInt(getUA('http://example.org'));
michael@0 132 ok(startTime <= updateTime, 'Update was before start time');
michael@0 133 ok(updateTime <= Date.now(), 'Update was after present time');
michael@0 134
michael@0 135 OVERRIDES.forEach(function (val) {
michael@0 136 val.expected && is(getUA(val.host), val.expected,
michael@0 137 'Incorrect URL parameter: ' + val.override);
michael@0 138 });
michael@0 139 callback();
michael@0 140 }, 100));
michael@0 141 }
michael@0 142
michael@0 143 function testBadUpdate(callback) {
michael@0 144 var url = getServerURL() + 'invalid-json';
michael@0 145 var prevOverride = navigator.userAgent;
michael@0 146 SpecialPowers.pushPrefEnv({
michael@0 147 set: [
michael@0 148 [PREF_UPDATES_URL, url],
michael@0 149 [PREF_UPDATES_INTERVAL, 1] // 1 second interval
michael@0 150 ]
michael@0 151 }, function () setTimeout(function () {
michael@0 152 // We want to make sure a bad update doesn't cancel out previous overrides.
michael@0 153 // We do this by waiting for 5 seconds (assuming the update occurs within 5
michael@0 154 // seconds), and check that the previous override hasn't changed.
michael@0 155 is(navigator.userAgent, prevOverride,
michael@0 156 'Invalid update deleted previous override');
michael@0 157 callback();
michael@0 158 }, 5000));
michael@0 159 }
michael@0 160
michael@0 161 function testProfileLoad(callback) {
michael@0 162 var file = FU.getFile(KEY_APPDIR, [FILE_UPDATES]).path;
michael@0 163 var encoder = SpecialPowers.wrap(new TextEncoder());
michael@0 164 var overrides = {};
michael@0 165 overrides[location.hostname] = UA_ALT_OVERRIDE;
michael@0 166 var bytes = encoder.encode(JSON.stringify(overrides));
michael@0 167
michael@0 168 var badfile = FU.getFile(KEY_PREFDIR, [FILE_UPDATES]).path;
michael@0 169 var badbytes = encoder.encode("null");
michael@0 170
michael@0 171 OSF.writeAtomic(file, bytes, {tmpPath: file + ".tmp"}).then(
michael@0 172 () => OSF.writeAtomic(badfile, badbytes, {tmpPath: badfile + ".tmp"})
michael@0 173 ).then(
michael@0 174 () => {
michael@0 175 SpecialPowers.pushPrefEnv({
michael@0 176 set: [[PREF_UPDATES_ENABLED, true]]
michael@0 177 }, function () {
michael@0 178 // initialize UserAgentOverrides.jsm and
michael@0 179 // UserAgentUpdates.jsm and load saved file
michael@0 180 UAO.init();
michael@0 181 (function waitForLoad() {
michael@0 182 if (navigator.userAgent !== UA_ALT_OVERRIDE) {
michael@0 183 setTimeout(waitForLoad, 100);
michael@0 184 return;
michael@0 185 }
michael@0 186 is(getUA(location.origin), UA_ALT_OVERRIDE, 'Did not apply saved override');
michael@0 187 saveFilePreviousSize = file.fileSize;
michael@0 188 callback();
michael@0 189 })();
michael@0 190 });
michael@0 191 },
michael@0 192 (reason) => {
michael@0 193 throw reason
michael@0 194 }
michael@0 195 );
michael@0 196 }
michael@0 197
michael@0 198 function testProfileSave(callback) {
michael@0 199 info('Waiting for saving to profile');
michael@0 200 var file = FU.getFile(KEY_PREFDIR, [FILE_UPDATES]).path;
michael@0 201 (function waitForSave() {
michael@0 202 OSF.exists(file).then(
michael@0 203 (exists) => {
michael@0 204 if (!exists) {
michael@0 205 setTimeout(waitForSave, 100);
michael@0 206 return;
michael@0 207 }
michael@0 208 return OSF.read(file).then(
michael@0 209 (bytes) => {
michael@0 210 info('Saved new overrides');
michael@0 211 var decoder = SpecialPowers.wrap(new TextDecoder());
michael@0 212 var overrides = JSON.parse(decoder.decode(bytes));
michael@0 213 is(overrides[location.hostname], UA_OVERRIDE, 'Incorrect saved override');
michael@0 214 OVERRIDES.forEach(function (val) {
michael@0 215 val.expected && is(overrides[val.domain], val.expected,
michael@0 216 'Incorrect saved override: ' + val.override);
michael@0 217 });
michael@0 218 callback();
michael@0 219 }
michael@0 220 );
michael@0 221 }
michael@0 222 ).then(null,
michael@0 223 (reason) => {
michael@0 224 throw reason
michael@0 225 }
michael@0 226 );
michael@0 227 })();
michael@0 228 }
michael@0 229
michael@0 230 SimpleTest.waitForExplicitFinish();
michael@0 231
michael@0 232 SpecialPowers.Cu.import("resource://gre/modules/FileUtils.jsm", window);
michael@0 233 var FU = SpecialPowers.wrap(FileUtils);
michael@0 234
michael@0 235 SpecialPowers.Cu.import("resource://gre/modules/osfile.jsm", window);
michael@0 236 var OSF = SpecialPowers.wrap(OS).File;
michael@0 237
michael@0 238 // Load UserAgentOverrides.jsm after we load update timer manager
michael@0 239 var UAO = null;
michael@0 240
michael@0 241 var saveFilePreviousSize = 0;
michael@0 242
michael@0 243 SpecialPowers.pushPrefEnv({
michael@0 244 set: [
michael@0 245 [PREF_APP_UPDATE_TIMERMINIMUMDELAY, 0]
michael@0 246 ]
michael@0 247 }, function () {
michael@0 248 // Enter update timer manager test mode
michael@0 249 (SpecialPowers.Cc["@mozilla.org/updates/timer-manager;1"].getService(
michael@0 250 SpecialPowers.Ci.nsIObserver)).observe(null, "utm-test-init", "");
michael@0 251
michael@0 252 SpecialPowers.Cu.import('resource://gre/modules/UserAgentOverrides.jsm', window);
michael@0 253 UAO = SpecialPowers.wrap(UserAgentOverrides);
michael@0 254 UAO.uninit();
michael@0 255
michael@0 256 // testProfileLoad, testDownload, and testProfileSave must run in this order
michael@0 257 // because testDownload depends on testProfileLoad to call UAO.init()
michael@0 258 // and testProfileSave depends on testDownload to save overrides to the profile
michael@0 259 testProfileLoad(function()
michael@0 260 testDownload(function()
michael@0 261 testBadUpdate(function()
michael@0 262 testProfileSave(SimpleTest.finish)
michael@0 263 )
michael@0 264 )
michael@0 265 );
michael@0 266 });
michael@0 267
michael@0 268 </script>
michael@0 269 </pre>
michael@0 270 </body>
michael@0 271 </html>
michael@0 272

mercurial