Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code

Side by Side Diff: test/synchronizer.js

Issue 29355872: Issue 4223 - Adapt synchronizer tests to work in adblockpluscore repository (Closed) Base URL: https://hg.adblockplus.org/adblockpluscore
Patch Set: Created Oct. 5, 2016, 8:05 a.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff | Download patch
« test/_common.js ('K') | « test/stub-modules/utils.js ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 (function() 1 /*
2 { 2 * This file is part of Adblock Plus <https://adblockplus.org/>,
3 let testRunner = null; 3 * Copyright (C) 2006-2016 Eyeo GmbH
4 let requestHandlers = null; 4 *
5 * Adblock Plus is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 3 as
7 * published by the Free Software Foundation.
8 *
9 * Adblock Plus is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18 "use strict";
19
20 let {createSandbox} = require("./_common");
21
22 const MILLIS_IN_SECOND = 1000;
23 const MILLIS_IN_MINUTE = 60 * MILLIS_IN_SECOND;
24 const MILLIS_IN_HOUR = 60 * MILLIS_IN_MINUTE;
25 const MILLIS_IN_DAY = 24 * MILLIS_IN_HOUR;
26
27 const Cr = {
28 NS_OK: 0,
29 NS_BINDING_ABORTED: 0x804B0002,
30 NS_ERROR_FAILURE: 0x80004005
31 }
32
33 let Filter = null;
34 let FilterStorage = null;
35 let Prefs = null;
36 let Subscription = null;
37 let Synchronizer = null;
38
39 exports.setUp = function(callback)
40 {
41 let currentTime = 100000 * MILLIS_IN_HOUR;
42 let startTime = currentTime;
43
44 let fakeTimer = {
45 callback: null,
46 delay: -1,
47 nextExecution: 0,
48
49 initWithCallback: function(callback, delay, type)
50 {
51 if (this.callback)
52 throw new Error("Only one timer instance supported");
53 if (type != 1)
54 throw new Error("Only TYPE_REPEATING_SLACK timers supported");
55
56 this.callback = callback;
57 this.delay = delay;
58 this.nextExecution = currentTime + delay;
59 },
60
61 trigger: function()
62 {
63 if (currentTime < this.nextExecution)
64 currentTime = this.nextExecution;
65 try
66 {
67 this.callback();
68 }
69 finally
70 {
71 this.nextExecution = currentTime + this.delay;
72 }
73 },
74
75 cancel: function()
76 {
77 this.nextExecution = -1;
78 }
79 };
80
81 let requests = [];
82 function XMLHttpRequest()
83 {
84 this._host = "http://example.com";
85 this._loadHandlers = [];
86 this._errorHandlers = [];
87 };
88 XMLHttpRequest.prototype =
89 {
90 _path: null,
91 _data: null,
92 _queryString: null,
93 _loadHandlers: null,
94 _errorHandlers: null,
95 status: 0,
96 readyState: 0,
97 responseText: null,
98
99 addEventListener: function(eventName, handler, capture)
100 {
101 let list;
102 if (eventName == "load")
103 list = this._loadHandlers;
104 else if (eventName == "error")
105 list = this._errorHandlers;
106 else
107 throw new Error("Event type " + eventName + " not supported");
108
109 if (list.indexOf(handler) < 0)
110 list.push(handler);
111 },
112
113 removeEventListener: function(eventName, handler, capture)
114 {
115 let list;
116 if (eventName == "load")
117 list = this._loadHandlers;
118 else if (eventName == "error")
119 list = this._errorHandlers;
120 else
121 throw new Error("Event type " + eventName + " not supported");
122
123 let index = list.indexOf(handler);
124 if (index >= 0)
125 list.splice(index, 1);
126 },
127
128 open: function(method, url, async, user, password)
129 {
130 if (method != "GET")
131 throw new Error("Only GET requests are supported");
132 if (typeof async != "undefined" && !async)
133 throw new Error("Sync requests are not supported");
134 if (typeof user != "undefined" || typeof password != "undefined")
135 throw new Error("User authentification is not supported");
136
137 let match = /^data:[^,]+,/.exec(url);
138 if (match)
139 {
140 this._data = decodeURIComponent(url.substr(match[0].length));
141 return;
142 }
143
144 if (url.substr(0, this._host.length + 1) != this._host + "/")
145 throw new Error("Unexpected URL: " + url + " (URL starting with " + this ._host + "expected)");
146
147 this._path = url.substr(this._host.length);
148
149 let queryIndex = this._path.indexOf("?");
150 this._queryString = "";
151 if (queryIndex >= 0)
152 {
153 this._queryString = this._path.substr(queryIndex + 1);
154 this._path = this._path.substr(0, queryIndex);
155 }
156 },
157
158 send: function(data)
159 {
160 if (!this._data && !this._path)
161 throw new Error("No request path set");
162 if (typeof data != "undefined" && data)
163 throw new Error("Sending data to server is not supported");
164
165 requests.push(Promise.resolve().then(() =>
166 {
167 let result = [Cr.NS_OK, 404, ""];
168 if (this._data)
169 result = [Cr.NS_OK, 0, this._data];
170 else if (this._path in XMLHttpRequest.requestHandlers)
171 {
172 result = XMLHttpRequest.requestHandlers[this._path]({
173 method: "GET",
174 path: this._path,
175 queryString: this._queryString
176 });
177 }
178
179 [this.channel.status, this.channel.responseStatus, this.responseText] = result;
180 this.status = this.channel.responseStatus;
181
182 let eventName = (this.channel.status == Cr.NS_OK ? "load" : "error");
183 let event = {type: eventName};
184 for (let handler of this["_" + eventName + "Handlers"])
185 handler.call(this, event);
186 }));
187 },
188
189 overrideMimeType: function(mime)
190 {
191 },
192
193 channel:
194 {
195 status: -1,
196 responseStatus: 0,
197 loadFlags: 0,
198 INHIBIT_CACHING: 0,
199 VALIDATE_ALWAYS: 0,
200 QueryInterface: () => this
201 }
202 };
203
204 XMLHttpRequest.requestHandlers = {};
205 this.registerHandler = (path, handler) =>
206 {
207 XMLHttpRequest.requestHandlers[path] = handler;
208 };
209
210 function waitForRequests()
211 {
212 if (requests.length)
213 {
214 let result = Promise.all(requests);
215 requests = [];
216 return result.catch(e =>
217 {
218 console.error(e);
219 }).then(() => waitForRequests());
220 }
221 else
222 return Promise.resolve();
223 }
224
225 function runScheduledTasks(maxMillis)
226 {
227 let endTime = currentTime + maxMillis;
228 if (fakeTimer.nextExecution < 0 || fakeTimer.nextExecution > endTime)
229 {
230 currentTime = endTime;
231 return Promise.resolve();
232 }
233 else
234 {
235 fakeTimer.trigger();
236 return waitForRequests().then(() => runScheduledTasks(endTime - currentTim e));
237 }
238
239 currentTime = endTime;
240 }
241
242 this.runScheduledTasks = (maxHours, initial, skip) =>
243 {
244 if (typeof maxHours != "number")
245 throw new Error("Numerical parameter expected");
246 if (typeof initial != "number")
247 initial = 0;
248 if (typeof skip != "number")
249 skip = 0;
250
251 startTime = currentTime;
252 return Promise.resolve().then(() =>
253 {
254 if (initial >= 0)
255 {
256 maxHours -= initial;
257 return runScheduledTasks(initial * MILLIS_IN_HOUR);
258 }
259 }).then(() =>
260 {
261 if (skip >= 0)
262 {
263 maxHours -= skip;
264 currentTime += skip * MILLIS_IN_HOUR;
265 }
266 return runScheduledTasks(maxHours * MILLIS_IN_HOUR);
267 });
268 };
269
270 this.getTimeOffset = () => (currentTime - startTime) / MILLIS_IN_HOUR;
271 Object.defineProperty(this, "currentTime", {
272 get: () => currentTime
273 });
274
5 let randomResult = 0.5; 275 let randomResult = 0.5;
6 276 Object.defineProperty(this, "randomResult", {
7 module("Synchronizer", { 277 get: () => randomResult,
8 setup: function() 278 set: value => randomResult = value
9 { 279 });
10 testRunner = this; 280
11 281 let sandboxedRequire = createSandbox({
12 prepareFilterComponents.call(this); 282 globals: {
13 preparePrefs.call(this); 283 Cc: {
14 284 "@mozilla.org/timer;1": {
15 Synchronizer.init(); 285 createInstance: () => fakeTimer
16 286 }
17 setupVirtualTime.call(this, function(wrapTimer) 287 },
18 { 288 Ci: {
19 let SynchronizerModule = getModuleGlobal("synchronizer"); 289 nsITimer:
20 SynchronizerModule.downloader._timer = wrapTimer(SynchronizerModule.down loader._timer); 290 {
21 }, "synchronizer", "downloader"); 291 TYPE_ONE_SHOT: 0,
22 setupVirtualXMLHttp.call(this, "synchronizer", "downloader"); 292 TYPE_REPEATING_SLACK: 1,
23 293 TYPE_REPEATING_PRECISE: 2
24 // Replace Math.random() function 294 },
25 let DownloaderGlobal = Cu.getGlobalForObject(getModuleGlobal("downloader") ); 295 nsIHttpChannel: () => null,
26 this._origRandom = DownloaderGlobal.Math.random; 296 },
27 DownloaderGlobal.Math.random = () => randomResult; 297 Cr: Cr,
28 randomResult = 0.5; 298 XMLHttpRequest: XMLHttpRequest,
29 }, 299 Date: {
30 300 now: () => currentTime
31 teardown: function() 301 },
32 { 302 Math: {
33 restoreFilterComponents.call(this); 303 random: () => randomResult,
34 restorePrefs.call(this); 304 min: Math.min,
35 restoreVirtualTime.call(this); 305 max: Math.max,
36 restoreVirtualXMLHttp.call(this); 306 round: Math.round
37 307 },
38 if (this._origRandom) 308 URL: function(urlString)
39 { 309 {
40 let DownloaderGlobal = Cu.getGlobalForObject(getModuleGlobal("downloader ")); 310 return require("url").parse(urlString);
41 DownloaderGlobal.Math.random = this._origRandom;
42 delete this._origRandom;
43 } 311 }
44
45 Synchronizer.init();
46 } 312 }
47 }); 313 });
48 314
49 function resetSubscription(subscription) 315 (
50 { 316 {Filter} = sandboxedRequire("../lib/filterClasses"),
51 FilterStorage.updateSubscriptionFilters(subscription, []); 317 {FilterStorage} = sandboxedRequire("../lib/filterStorage"),
52 subscription.lastCheck = subscription.lastDownload = 318 {Prefs} = sandboxedRequire("./stub-modules/prefs"),
53 subscription.version = subscription.lastSuccess = 319 {Subscription} = sandboxedRequire("../lib/subscriptionClasses"),
54 subscription.expires = subscription.softExpiration = 0; 320 {Synchronizer} = sandboxedRequire("../lib/synchronizer")
55 subscription.title = ""; 321 );
56 subscription.homepage = null; 322
57 subscription.errors = 0; 323 callback();
58 subscription.downloadStatus = null; 324 };
59 subscription.requiredVersion = null; 325
60 } 326 function unexpectedError(error)
61 327 {
62 let initialDelay = 1 / 60; 328 console.error(error);
63 329 this.ok(false, "Unexpected error: " + error);
64 test("Downloads of one subscription", function() 330 }
65 { 331
66 let subscription = Subscription.fromURL("http://example.com/subscription"); 332 function resetSubscription(subscription)
67 FilterStorage.addSubscription(subscription); 333 {
68 334 FilterStorage.updateSubscriptionFilters(subscription, []);
69 let requests = []; 335 subscription.lastCheck = subscription.lastDownload =
70 testRunner.registerHandler("/subscription", function(metadata) 336 subscription.version = subscription.lastSuccess =
71 { 337 subscription.expires = subscription.softExpiration = 0;
72 requests.push([testRunner.getTimeOffset(), metadata.method, metadata.path] ); 338 subscription.title = "";
73 return [Cr.NS_OK, 200, "[Adblock]\n! ExPiREs: 1day\nfoo\nbar"]; 339 subscription.homepage = null;
74 }); 340 subscription.errors = 0;
75 341 subscription.downloadStatus = null;
76 testRunner.runScheduledTasks(50); 342 subscription.requiredVersion = null;
77 deepEqual(requests, [ 343 }
344
345 let initialDelay = 1 / 60;
346
347 exports.testOneSubscriptionDownloads = function(test)
348 {
349 let subscription = Subscription.fromURL("http://example.com/subscription");
350 FilterStorage.addSubscription(subscription);
351
352 let requests = [];
353 this.registerHandler("/subscription", metadata =>
354 {
355 requests.push([this.getTimeOffset(), metadata.method, metadata.path]);
356 return [Cr.NS_OK, 200, "[Adblock]\n! ExPiREs: 1day\nfoo\nbar"];
357 });
358
359 this.runScheduledTasks(50).then(() =>
360 {
361 test.deepEqual(requests, [
78 [0 + initialDelay, "GET", "/subscription"], 362 [0 + initialDelay, "GET", "/subscription"],
79 [24 + initialDelay, "GET", "/subscription"], 363 [24 + initialDelay, "GET", "/subscription"],
80 [48 + initialDelay, "GET", "/subscription"], 364 [48 + initialDelay, "GET", "/subscription"],
81 ], "Requests after 50 hours"); 365 ], "Requests after 50 hours");
82 }); 366 }).catch(unexpectedError.bind(test)).then(() => test.done());
83 367 };
84 test("Downloads of two subscriptions", function() 368
85 { 369 exports.testTwoSubscriptionsDownloads = function(test)
86 let subscription1 = Subscription.fromURL("http://example.com/subscription1") ; 370 {
87 FilterStorage.addSubscription(subscription1); 371 let subscription1 = Subscription.fromURL("http://example.com/subscription1");
88 372 FilterStorage.addSubscription(subscription1);
89 let subscription2 = Subscription.fromURL("http://example.com/subscription2") ; 373
90 subscription2.expires = 374 let subscription2 = Subscription.fromURL("http://example.com/subscription2");
91 subscription2.softExpiration = 375 subscription2.expires =
92 (testRunner.currentTime + 2 * MILLIS_IN_HOUR) / MILLIS_IN_SECOND; 376 subscription2.softExpiration =
93 FilterStorage.addSubscription(subscription2); 377 (this.currentTime + 2 * MILLIS_IN_HOUR) / MILLIS_IN_SECOND;
94 378 FilterStorage.addSubscription(subscription2);
95 let requests = []; 379
96 function handler(metadata) 380 let requests = [];
97 { 381 let handler = metadata =>
98 requests.push([testRunner.getTimeOffset(), metadata.method, metadata.path] ); 382 {
99 return [Cr.NS_OK, 200, "[Adblock]\n! ExPiREs: 1day\nfoo\nbar"]; 383 requests.push([this.getTimeOffset(), metadata.method, metadata.path]);
100 } 384 return [Cr.NS_OK, 200, "[Adblock]\n! ExPiREs: 1day\nfoo\nbar"];
101 385 };
102 testRunner.registerHandler("/subscription1", handler); 386
103 testRunner.registerHandler("/subscription2", handler); 387 this.registerHandler("/subscription1", handler);
104 388 this.registerHandler("/subscription2", handler);
105 testRunner.runScheduledTasks(55); 389
106 deepEqual(requests, [ 390 this.runScheduledTasks(55).then(() =>
391 {
392 test.deepEqual(requests, [
107 [0 + initialDelay, "GET", "/subscription1"], 393 [0 + initialDelay, "GET", "/subscription1"],
108 [2 + initialDelay, "GET", "/subscription2"], 394 [2 + initialDelay, "GET", "/subscription2"],
109 [24 + initialDelay, "GET", "/subscription1"], 395 [24 + initialDelay, "GET", "/subscription1"],
110 [26 + initialDelay, "GET", "/subscription2"], 396 [26 + initialDelay, "GET", "/subscription2"],
111 [48 + initialDelay, "GET", "/subscription1"], 397 [48 + initialDelay, "GET", "/subscription1"],
112 [50 + initialDelay, "GET", "/subscription2"], 398 [50 + initialDelay, "GET", "/subscription2"],
113 ], "Requests after 55 hours"); 399 ], "Requests after 55 hours");
114 }); 400 }).catch(unexpectedError.bind(test)).then(() => test.done());
115 401 };
116 test("Download result, various subscription headers", function() 402
117 { 403 exports.testSubscriptionHeaders = function(test)
118 let test; 404 {
119 let subscription = Subscription.fromURL("http://example.com/subscription"); 405 let currentTest;
120 FilterStorage.addSubscription(subscription); 406 let subscription = Subscription.fromURL("http://example.com/subscription");
121 407 FilterStorage.addSubscription(subscription);
122 testRunner.registerHandler("/subscription", function(metadata) 408
123 { 409 this.registerHandler("/subscription", metadata =>
124 return [Cr.NS_OK, 200, test.header + "\n!Expires: 8 hours\nfoo\n!bar\n\n@@ bas\n#bam"]; 410 {
125 }); 411 return [Cr.NS_OK, 200, currentTest.header + "\n!Expires: 8 hours\nfoo\n!bar\ n\n@@bas\n#bam"];
126 412 });
127 let tests = [ 413
128 {header: "[Adblock]", downloadStatus: "synchronize_ok", requiredVersion: n ull}, 414 let tests = [
129 {header: "[Adblock Plus]", downloadStatus: "synchronize_ok", requiredVersi on: null}, 415 {header: "[Adblock]", downloadStatus: "synchronize_ok", requiredVersion: nul l},
130 {header: "(something)[Adblock]", downloadStatus: "synchronize_ok", require dVersion: null}, 416 {header: "[Adblock Plus]", downloadStatus: "synchronize_ok", requiredVersion : null},
131 {header: "[Adblock Plus 0.0.1]", downloadStatus: "synchronize_ok", require dVersion: "0.0.1"}, 417 {header: "(something)[Adblock]", downloadStatus: "synchronize_ok", requiredV ersion: null},
132 {header: "[Adblock Plus 99.9]", downloadStatus: "synchronize_ok", required Version: "99.9"}, 418 {header: "[Adblock Plus 0.0.1]", downloadStatus: "synchronize_ok", requiredV ersion: "0.0.1"},
133 {header: "[Foo]", downloadStatus: "synchronize_invalid_data", requiredVers ion: null} 419 {header: "[Adblock Plus 99.9]", downloadStatus: "synchronize_ok", requiredVe rsion: "99.9"},
134 ]; 420 {header: "[Foo]", downloadStatus: "synchronize_invalid_data", requiredVersio n: null}
135 for (test of tests) 421 ];
136 { 422
137 resetSubscription(subscription) 423 let runTest = () =>
138 testRunner.runScheduledTasks(2); 424 {
139 425 if (!tests.length)
140 equal(subscription.downloadStatus, test.downloadStatus, "Download status f or " + test.header) 426 return;
141 equal(subscription.requiredVersion, test.requiredVersion, "Required versio n for " + test.header) 427
142 428 currentTest = tests.shift();
143 if (test.downloadStatus == "synchronize_ok") 429
144 { 430 resetSubscription(subscription)
145 deepEqual(subscription.filters, [ 431 return this.runScheduledTasks(2).then(() =>
432 {
433 test.equal(subscription.downloadStatus, currentTest.downloadStatus, "Downl oad status for " + currentTest.header);
434 test.equal(subscription.requiredVersion, currentTest.requiredVersion, "Req uired version for " + currentTest.header);
435
436 if (currentTest.downloadStatus == "synchronize_ok")
437 {
438 test.deepEqual(subscription.filters, [
146 Filter.fromText("foo"), 439 Filter.fromText("foo"),
147 Filter.fromText("!bar"), 440 Filter.fromText("!bar"),
148 Filter.fromText("@@bas"), 441 Filter.fromText("@@bas"),
149 Filter.fromText("#bam"), 442 Filter.fromText("#bam"),
150 ], "Resulting subscription filters for " + test.header); 443 ], "Resulting subscription filters for " + currentTest.header);
151 } 444 }
152 else 445 else
153 { 446 {
154 deepEqual(subscription.filters, [ 447 test.deepEqual(subscription.filters, [
155 ], "Resulting subscription filters for " + test.header); 448 ], "Resulting subscription filters for " + currentTest.header);
156 } 449 }
450 }).then(runTest);
451 };
452
453 runTest().catch(unexpectedError.bind(test)).then(() => test.done());
454 };
455
456 exports.testsDisabledUpdates = function(test)
457 {
458 Prefs.subscriptions_autoupdate = false;
459
460 let subscription = Subscription.fromURL("http://example.com/subscription");
461 FilterStorage.addSubscription(subscription);
462
463 let requests = 0;
464 this.registerHandler("/subscription", metadata =>
465 {
466 requests++;
467 throw new Error("Unexpected request");
468 });
469
470 this.runScheduledTasks(50).then(() =>
471 {
472 test.equal(requests, 0, "Request count");
473 }).catch(unexpectedError.bind(test)).then(() => test.done());
474 };
475
476 exports.testExpirationTime = function(test)
477 {
478 let subscription = Subscription.fromURL("http://example.com/subscription");
479 FilterStorage.addSubscription(subscription);
480
481 let currentTest;
482 let requests = [];
483 this.registerHandler("/subscription", metadata =>
484 {
485 requests.push(this.getTimeOffset());
486 return [Cr.NS_OK, 200, "[Adblock]\nfoo\n!Expires: " + currentTest.expiration + "\nbar"];
487 });
488
489 let tests = [
490 {
491 expiration: "default",
492 randomResult: 0.5,
493 requests: [0 + initialDelay, 5 * 24 + initialDelay]
494 },
495 {
496 expiration: "1 hours", // Minimal expiration interval
497 randomResult: 0.5,
498 requests: [0 + initialDelay, 1 + initialDelay, 2 + initialDelay, 3 + initi alDelay]
499 },
500 {
501 expiration: "26 hours",
502 randomResult: 0.5,
503 requests: [0 + initialDelay, 26 + initialDelay]
504 },
505 {
506 expiration: "2 days",
507 randomResult: 0.5,
508 requests: [0 + initialDelay, 48 + initialDelay]
509 },
510 {
511 expiration: "20 days", // Too large, will be corrected
512 randomResult: 0.5,
513 requests: [0 + initialDelay, 14 * 24 + initialDelay]
514 },
515 {
516 expiration: "35 hours",
517 randomResult: 0, // Changes interval by factor 0.8
518 requests: [0 + initialDelay, 28 + initialDelay]
519 },
520 {
521 expiration: "35 hours",
522 randomResult: 1, // Changes interval by factor 1.2
523 requests: [0 + initialDelay, 42 + initialDelay]
524 },
525 {
526 expiration: "35 hours",
527 randomResult: 0.25, // Changes interval by factor 0.9
528 requests: [0 + initialDelay, 32 + initialDelay]
529 },
530 {
531 expiration: "40 hours",
532 randomResult: 0.5,
533 skipAfter: 5 + initialDelay,
534 skip: 10, // Short break should not increase soft expiration
535 requests: [0 + initialDelay, 40 + initialDelay]
536 },
537 {
538 expiration: "40 hours",
539 randomResult: 0.5,
540 skipAfter: 5 + initialDelay,
541 skip: 30, // Long break should increase soft expiration
542 requests: [0 + initialDelay, 70 + initialDelay]
543 },
544 {
545 expiration: "40 hours",
546 randomResult: 0.5,
547 skipAfter: 5 + initialDelay,
548 skip: 80, // Hitting hard expiration, immediate download
549 requests: [0 + initialDelay, 85 + initialDelay]
157 } 550 }
158 }) 551 ]
159 552
160 test("Automatic updates disabled", function() 553 let runTest = () =>
161 { 554 {
162 Prefs.subscriptions_autoupdate = false; 555 if (!tests.length)
163 556 return;
164 let subscription = Subscription.fromURL("http://example.com/subscription"); 557
165 FilterStorage.addSubscription(subscription); 558 currentTest = tests.shift();
166 559
167 let requests = 0; 560 requests = [];
168 testRunner.registerHandler("/subscription", function(metadata) 561 this.randomResult = currentTest.randomResult;
169 { 562 resetSubscription(subscription);
170 requests++; 563
171 throw new Error("Unexpected request"); 564 let maxHours = Math.round(Math.max.apply(null, currentTest.requests)) + 1;
172 }); 565 return this.runScheduledTasks(maxHours, currentTest.skipAfter, currentTest.s kip).then(() =>
173 566 {
174 testRunner.runScheduledTasks(50); 567 let randomAddendum = (this.randomResult == 0.5 ? "" : " with Math.random() returning " + this.randomResult);
175 equal(requests, 0, "Request count"); 568 let skipAddendum = (typeof currentTest.skip != "number" ? "" : " skipping " + currentTest.skip + " hours after " + currentTest.skipAfter + " hours");
176 }); 569 test.deepEqual(requests, currentTest.requests, "Requests for \"" + current Test.expiration + "\"" + randomAddendum + skipAddendum);
177 570 }).then(runTest);
178 test("Expiration time", function() 571 };
179 { 572
180 let subscription = Subscription.fromURL("http://example.com/subscription"); 573 runTest().catch(unexpectedError.bind(test)).then(() => test.done());
181 FilterStorage.addSubscription(subscription); 574 };
182 575
183 let test; 576 exports.testChecksumVerification = function(test)
184 let requests = []; 577 {
185 testRunner.registerHandler("/subscription", function(metadata) 578 let subscription = Subscription.fromURL("http://example.com/subscription");
186 { 579 FilterStorage.addSubscription(subscription);
187 requests.push(testRunner.getTimeOffset()); 580
188 return [Cr.NS_OK, 200, "[Adblock]\nfoo\n!Expires: " + test.expiration + "\ nbar"]; 581 let testName, subscriptionBody, expectedResult;
189 }); 582 let tests = [
190 583 ["Correct checksum", "[Adblock]\n! Checksum: e/JCmqXny6Fn24b7JHsq/A\nfoo\nba r\n", true],
191 let tests = [ 584 ["Wrong checksum", "[Adblock]\n! Checksum: wrongggny6Fn24b7JHsq/A\nfoo\nbar\ n", false],
192 { 585 ["Empty lines ignored", "[Adblock]\n! Checksum: e/JCmqXny6Fn24b7JHsq/A\n\nfo o\n\nbar\n\n", true],
193 expiration: "default", 586 ["CR LF line breaks treated like LR", "[Adblock]\n! Checksum: e/JCmqXny6Fn24 b7JHsq/A\nfoo\r\nbar\r\n", true],
194 randomResult: 0.5, 587 ["CR line breaks treated like LR", "[Adblock]\n! Checksum: e/JCmqXny6Fn24b7J Hsq/A\nfoo\rbar\r", true],
195 requests: [0 + initialDelay, 5 * 24 + initialDelay] 588 ["Trailing line break not ignored", "[Adblock]\n! Checksum: e/JCmqXny6Fn24b7 JHsq/A\nfoo\nbar", false],
196 }, 589 ["Line breaks between lines not ignored", "[Adblock]\n! Checksum: e/JCmqXny6 Fn24b7JHsq/A\nfoobar", false],
197 { 590 ["Lines with spaces not ignored", "[Adblock]\n! Checksum: e/JCmqXny6Fn24b7JH sq/A\n \nfoo\n\nbar\n", false],
198 expiration: "1 hours", // Minimal expiration interval 591 ["Extra content in checksum line is part of the checksum", "[Adblock]\n! Che cksum: e/JCmqXny6Fn24b7JHsq/A foobar\nfoo\nbar\n", false],
199 randomResult: 0.5, 592 ["= symbols after checksum are ignored", "[Adblock]\n! Checksum: e/JCmqXny6F n24b7JHsq/A===\nfoo\nbar\n", true],
200 requests: [0 + initialDelay, 1 + initialDelay, 2 + initialDelay, 3 + ini tialDelay] 593 ["Header line is part of the checksum", "[Adblock Plus]\n! Checksum: e/JCmqX ny6Fn24b7JHsq/A\nfoo\nbar\n", false],
201 }, 594 ["Special comments are part of the checksum", "[Adblock]\n! Checksum: e/JCmq Xny6Fn24b7JHsq/A\n! Expires: 1\nfoo\nbar\n", false],
202 { 595 ];
203 expiration: "26 hours", 596
204 randomResult: 0.5, 597 this.registerHandler("/subscription", metadata =>
205 requests: [0 + initialDelay, 26 + initialDelay] 598 {
206 }, 599 return [Cr.NS_OK, 200, subscriptionBody];
207 { 600 });
208 expiration: "2 days", 601
209 randomResult: 0.5, 602 let runTest = () =>
210 requests: [0 + initialDelay, 48 + initialDelay] 603 {
211 }, 604 if (!tests.length)
212 { 605 return;
213 expiration: "20 days", // Too large, will be corrected 606
214 randomResult: 0.5, 607 [testName, subscriptionBody, expectedResult] = tests.shift();
215 requests: [0 + initialDelay, 14 * 24 + initialDelay] 608
216 }, 609 resetSubscription(subscription);
217 { 610 return this.runScheduledTasks(2).then(() =>
218 expiration: "35 hours", 611 {
219 randomResult: 0, // Changes interval by factor 0.8 612 test.equal(subscription.downloadStatus, expectedResult ? "synchronize_ok" : "synchronize_checksum_mismatch", testName);
220 requests: [0 + initialDelay, 28 + initialDelay] 613 }).then(runTest);
221 }, 614 };
222 { 615
223 expiration: "35 hours", 616 runTest().catch(unexpectedError.bind(test)).then(() => test.done());
224 randomResult: 1, // Changes interval by factor 1.2 617 };
225 requests: [0 + initialDelay, 42 + initialDelay] 618
226 }, 619 exports.testSpecialComments = function(test)
227 { 620 {
228 expiration: "35 hours", 621 let subscription = Subscription.fromURL("http://example.com/subscription");
229 randomResult: 0.25, // Changes interval by factor 0.9 622 FilterStorage.addSubscription(subscription);
230 requests: [0 + initialDelay, 32 + initialDelay] 623
231 }, 624 let comment, check;
232 { 625 let tests = [
233 expiration: "40 hours", 626 ["! Homepage: http://example.com/", () => test.equal(subscription.homepage, "http://example.com/", "Valid homepage comment")],
234 randomResult: 0.5, 627 ["! Homepage: ssh://example.com/", () => test.equal(subscription.homepage, n ull, "Invalid homepage comment")],
235 skipAfter: 5 + initialDelay, 628 ["! Title: foo", function()
236 skip: 10, // Short break should not increase soft expirati on 629 {
237 requests: [0 + initialDelay, 40 + initialDelay] 630 test.equal(subscription.title, "foo", "Title comment");
238 }, 631 test.equal(subscription.fixedTitle, true, "Fixed title");
239 { 632 }],
240 expiration: "40 hours", 633 ["! Version: 1234", () => test.equal(subscription.version, 1234, "Version co mment")]
241 randomResult: 0.5, 634 ];
242 skipAfter: 5 + initialDelay, 635
243 skip: 30, // Long break should increase soft expiration 636 this.registerHandler("/subscription", metadata =>
244 requests: [0 + initialDelay, 70 + initialDelay] 637 {
245 }, 638 return [Cr.NS_OK, 200, "[Adblock]\n" + comment + "\nfoo\nbar"];
246 { 639 });
247 expiration: "40 hours", 640
248 randomResult: 0.5, 641 let runTest = () =>
249 skipAfter: 5 + initialDelay, 642 {
250 skip: 80, // Hitting hard expiration, immediate download 643 if (!tests.length)
251 requests: [0 + initialDelay, 85 + initialDelay] 644 return;
252 } 645
253 ] 646 [comment, check] = tests.shift();
254 647
255 for (test of tests) 648 resetSubscription(subscription);
256 { 649 return this.runScheduledTasks(2).then(() =>
257 requests = []; 650 {
258 randomResult = test.randomResult;
259 resetSubscription(subscription);
260
261 let maxHours = Math.round(Math.max.apply(null, test.requests)) + 1;
262 testRunner.runScheduledTasks(maxHours, test.skipAfter, test.skip);
263
264 let randomAddendum = (randomResult == 0.5 ? "" : " with Math.random() retu rning " + randomResult);
265 let skipAddendum = (typeof test.skip != "number" ? "" : " skipping " + tes t.skip + " hours after " + test.skipAfter + " hours");
266 deepEqual(requests, test.requests, "Requests for \"" + test.expiration + " \"" + randomAddendum + skipAddendum);
267 }
268 });
269
270 test("Checksum verification", function()
271 {
272 let subscription = Subscription.fromURL("http://example.com/subscription");
273 FilterStorage.addSubscription(subscription);
274
275 let testName, subscriptionBody, expectedResult;
276 let tests = [
277 ["Correct checksum", "[Adblock]\n! Checksum: e/JCmqXny6Fn24b7JHsq/A\nfoo\n bar\n", true],
278 ["Wrong checksum", "[Adblock]\n! Checksum: wrongggny6Fn24b7JHsq/A\nfoo\nba r\n", false],
279 ["Empty lines ignored", "[Adblock]\n! Checksum: e/JCmqXny6Fn24b7JHsq/A\n\n foo\n\nbar\n\n", true],
280 ["CR LF line breaks treated like LR", "[Adblock]\n! Checksum: e/JCmqXny6Fn 24b7JHsq/A\nfoo\r\nbar\r\n", true],
281 ["CR line breaks treated like LR", "[Adblock]\n! Checksum: e/JCmqXny6Fn24b 7JHsq/A\nfoo\rbar\r", true],
282 ["Trailing line break not ignored", "[Adblock]\n! Checksum: e/JCmqXny6Fn24 b7JHsq/A\nfoo\nbar", false],
283 ["Line breaks between lines not ignored", "[Adblock]\n! Checksum: e/JCmqXn y6Fn24b7JHsq/A\nfoobar", false],
284 ["Lines with spaces not ignored", "[Adblock]\n! Checksum: e/JCmqXny6Fn24b7 JHsq/A\n \nfoo\n\nbar\n", false],
285 ["Extra content in checksum line is part of the checksum", "[Adblock]\n! C hecksum: e/JCmqXny6Fn24b7JHsq/A foobar\nfoo\nbar\n", false],
286 ["= symbols after checksum are ignored", "[Adblock]\n! Checksum: e/JCmqXny 6Fn24b7JHsq/A===\nfoo\nbar\n", true],
287 ["Header line is part of the checksum", "[Adblock Plus]\n! Checksum: e/JCm qXny6Fn24b7JHsq/A\nfoo\nbar\n", false],
288 ["Special comments are part of the checksum", "[Adblock]\n! Checksum: e/JC mqXny6Fn24b7JHsq/A\n! Expires: 1\nfoo\nbar\n", false],
289 ];
290
291 testRunner.registerHandler("/subscription", function(metadata)
292 {
293 return [Cr.NS_OK, 200, subscriptionBody];
294 });
295
296 for ([testName, subscriptionBody, expectedResult] of tests)
297 {
298 resetSubscription(subscription);
299 testRunner.runScheduledTasks(2);
300 equal(subscription.downloadStatus, expectedResult ? "synchronize_ok" : "sy nchronize_checksum_mismatch", testName);
301 }
302 });
303
304 test("Special comments", function()
305 {
306 let subscription = Subscription.fromURL("http://example.com/subscription");
307 FilterStorage.addSubscription(subscription);
308
309 let comment, check;
310 let tests = [
311 ["! Homepage: http://example.com/", () => equal(subscription.homepage, "ht tp://example.com/", "Valid homepage comment")],
312 ["! Homepage: ssh://example.com/", () => equal(subscription.homepage, null , "Invalid homepage comment")],
313 ["! Title: foo", function()
314 {
315 equal(subscription.title, "foo", "Title comment");
316 equal(subscription.fixedTitle, true, "Fixed title");
317 }],
318 ["! Version: 1234", () => equal(subscription.version, 1234, "Version comme nt")]
319 ];
320
321 testRunner.registerHandler("/subscription", function(metadata)
322 {
323 return [Cr.NS_OK, 200, "[Adblock]\n" + comment + "\nfoo\nbar"];
324 });
325
326 for ([comment, check] of tests)
327 {
328 resetSubscription(subscription);
329 testRunner.runScheduledTasks(2);
330 check(); 651 check();
331 deepEqual(subscription.filters, [Filter.fromText("foo"), Filter.fromText(" bar")], "Special comment not added to filters"); 652 test.deepEqual(subscription.filters, [Filter.fromText("foo"), Filter.fromT ext("bar")], "Special comment not added to filters");
332 } 653 }).then(runTest);
333 }); 654 };
334 655
335 test("Redirects", function() 656 runTest().catch(unexpectedError.bind(test)).then(() => test.done());
336 { 657 };
337 let subscription = Subscription.fromURL("http://example.com/subscription"); 658
338 FilterStorage.addSubscription(subscription); 659 exports.testRedirects = function(test)
339 660 {
340 testRunner.registerHandler("/subscription", function(metadata) 661 let subscription = Subscription.fromURL("http://example.com/subscription");
341 { 662 FilterStorage.addSubscription(subscription);
342 return [Cr.NS_OK, 200, "[Adblock]\nfoo\n!Redirect: http://example.com/redi rected\nbar"]; 663
343 }); 664 this.registerHandler("/subscription", metadata =>
344 665 {
345 testRunner.runScheduledTasks(30); 666 return [Cr.NS_OK, 200, "[Adblock]\nfoo\n!Redirect: http://example.com/redire cted\nbar"];
346 equal(FilterStorage.subscriptions[0], subscription, "Invalid redirect ignore d"); 667 });
347 equal(subscription.downloadStatus, "synchronize_connection_error", "Connecti on error recorded"); 668
348 equal(subscription.errors, 2, "Number of download errors"); 669 let requests;
349 670
350 let requests = []; 671 this.runScheduledTasks(30).then(() =>
351 testRunner.registerHandler("/redirected", function(metadata) 672 {
352 { 673 test.equal(FilterStorage.subscriptions[0], subscription, "Invalid redirect i gnored");
353 requests.push(testRunner.getTimeOffset()); 674 test.equal(subscription.downloadStatus, "synchronize_connection_error", "Con nection error recorded");
675 test.equal(subscription.errors, 2, "Number of download errors");
676
677 requests = [];
678
679 this.registerHandler("/redirected", metadata =>
680 {
681 requests.push(this.getTimeOffset());
354 return [Cr.NS_OK, 200, "[Adblock]\nfoo\n! Expires: 8 hours\nbar"]; 682 return [Cr.NS_OK, 200, "[Adblock]\nfoo\n! Expires: 8 hours\nbar"];
355 }); 683 });
356 684
357 resetSubscription(subscription); 685 resetSubscription(subscription);
358 testRunner.runScheduledTasks(15); 686 return this.runScheduledTasks(15);
359 equal(FilterStorage.subscriptions[0].url, "http://example.com/redirected", " Redirect followed"); 687 }).then(() =>
360 deepEqual(requests, [0 + initialDelay, 8 + initialDelay], "Resulting request s"); 688 {
361 689 test.equal(FilterStorage.subscriptions[0].url, "http://example.com/redirecte d", "Redirect followed");
362 testRunner.registerHandler("/redirected", function(metadata) 690 test.deepEqual(requests, [0 + initialDelay, 8 + initialDelay], "Resulting re quests");
691
692 this.registerHandler("/redirected", metadata =>
363 { 693 {
364 return [Cr.NS_OK, 200, "[Adblock]\nfoo\n!Redirect: http://example.com/subs cription\nbar"]; 694 return [Cr.NS_OK, 200, "[Adblock]\nfoo\n!Redirect: http://example.com/subs cription\nbar"];
365 }) 695 })
366 696
367 subscription = Subscription.fromURL("http://example.com/subscription"); 697 subscription = Subscription.fromURL("http://example.com/subscription");
368 resetSubscription(subscription); 698 resetSubscription(subscription);
369 FilterStorage.removeSubscription(FilterStorage.subscriptions[0]); 699 FilterStorage.removeSubscription(FilterStorage.subscriptions[0]);
370 FilterStorage.addSubscription(subscription); 700 FilterStorage.addSubscription(subscription);
371 701
372 testRunner.runScheduledTasks(2); 702 return this.runScheduledTasks(2);
373 equal(FilterStorage.subscriptions[0], subscription, "Redirect not followed o n redirect loop"); 703 }).then(() =>
374 equal(subscription.downloadStatus, "synchronize_connection_error", "Download status after redirect loop"); 704 {
375 }); 705 test.equal(FilterStorage.subscriptions[0], subscription, "Redirect not follo wed on redirect loop");
376 706 test.equal(subscription.downloadStatus, "synchronize_connection_error", "Dow nload status after redirect loop");
377 test("Fallback", function() 707 }).catch(unexpectedError.bind(test)).then(() => test.done());
378 { 708 };
379 Prefs.subscriptions_fallbackerrors = 3; 709
380 Prefs.subscriptions_fallbackurl = "http://example.com/fallback?%SUBSCRIPTION %&%CHANNELSTATUS%&%RESPONSESTATUS%"; 710 exports.testFallback = function(test)
381 711 {
382 let subscription = Subscription.fromURL("http://example.com/subscription"); 712 Prefs.subscriptions_fallbackerrors = 3;
383 FilterStorage.addSubscription(subscription); 713 Prefs.subscriptions_fallbackurl = "http://example.com/fallback?%SUBSCRIPTION%& %CHANNELSTATUS%&%RESPONSESTATUS%";
384 714
385 // No valid response from fallback 715 let subscription = Subscription.fromURL("http://example.com/subscription");
386 716 FilterStorage.addSubscription(subscription);
387 let requests = []; 717
388 testRunner.registerHandler("/subscription", function(metadata) 718 // No valid response from fallback
389 { 719
390 requests.push(testRunner.getTimeOffset()); 720 let requests = [];
391 return [Cr.NS_OK, 404, ""]; 721 let fallbackParams;
392 }); 722 let redirectedRequests;
393 723 this.registerHandler("/subscription", metadata =>
394 testRunner.runScheduledTasks(100); 724 {
395 deepEqual(requests, [0 + initialDelay, 24 + initialDelay, 48 + initialDelay, 72 + initialDelay, 96 + initialDelay], "Continue trying if the fallback doesn't respond"); 725 requests.push(this.getTimeOffset());
726 return [Cr.NS_OK, 404, ""];
727 });
728
729 this.runScheduledTasks(100).then(() =>
730 {
731 test.deepEqual(requests, [0 + initialDelay, 24 + initialDelay, 48 + initialD elay, 72 + initialDelay, 96 + initialDelay], "Continue trying if the fallback do esn't respond");
396 732
397 // Fallback giving "Gone" response 733 // Fallback giving "Gone" response
398 734
399 resetSubscription(subscription); 735 resetSubscription(subscription);
400 requests = []; 736 requests = [];
401 fallbackParams = null; 737 fallbackParams = null;
402 testRunner.registerHandler("/fallback", function(metadata) 738 this.registerHandler("/fallback", metadata =>
403 { 739 {
404 fallbackParams = decodeURIComponent(metadata.queryString); 740 fallbackParams = decodeURIComponent(metadata.queryString);
405 return [Cr.NS_OK, 200, "410 Gone"]; 741 return [Cr.NS_OK, 200, "410 Gone"];
406 }); 742 });
407 743
408 testRunner.runScheduledTasks(100); 744 return this.runScheduledTasks(100);
409 deepEqual(requests, [0 + initialDelay, 24 + initialDelay, 48 + initialDelay] , "Stop trying if the fallback responds with Gone"); 745 }).then(() =>
410 equal(fallbackParams, "http://example.com/subscription&0&404", "Fallback arg uments"); 746 {
747 test.deepEqual(requests, [0 + initialDelay, 24 + initialDelay, 48 + initialD elay], "Stop trying if the fallback responds with Gone");
748 test.equal(fallbackParams, "http://example.com/subscription&0&404", "Fallbac k arguments");
411 749
412 // Fallback redirecting to a missing file 750 // Fallback redirecting to a missing file
413 751
414 subscription = Subscription.fromURL("http://example.com/subscription"); 752 subscription = Subscription.fromURL("http://example.com/subscription");
415 resetSubscription(subscription); 753 resetSubscription(subscription);
416 FilterStorage.removeSubscription(FilterStorage.subscriptions[0]); 754 FilterStorage.removeSubscription(FilterStorage.subscriptions[0]);
417 FilterStorage.addSubscription(subscription); 755 FilterStorage.addSubscription(subscription);
418 requests = []; 756 requests = [];
419 757
420 testRunner.registerHandler("/fallback", function(metadata) 758 this.registerHandler("/fallback", metadata =>
421 { 759 {
422 return [Cr.NS_OK, 200, "301 http://example.com/redirected"]; 760 return [Cr.NS_OK, 200, "301 http://example.com/redirected"];
423 }); 761 });
424 testRunner.runScheduledTasks(100); 762 return this.runScheduledTasks(100);
425 equal(FilterStorage.subscriptions[0].url, "http://example.com/subscription", "Ignore invalid redirect from fallback"); 763 }).then(() =>
426 deepEqual(requests, [0 + initialDelay, 24 + initialDelay, 48 + initialDelay, 72 + initialDelay, 96 + initialDelay], "Requests not affected by invalid redire ct"); 764 {
765 test.equal(FilterStorage.subscriptions[0].url, "http://example.com/subscript ion", "Ignore invalid redirect from fallback");
766 test.deepEqual(requests, [0 + initialDelay, 24 + initialDelay, 48 + initialD elay, 72 + initialDelay, 96 + initialDelay], "Requests not affected by invalid r edirect");
427 767
428 // Fallback redirecting to an existing file 768 // Fallback redirecting to an existing file
429 769
430 resetSubscription(subscription); 770 resetSubscription(subscription);
431 requests = []; 771 requests = [];
432 let redirectedRequests = []; 772 redirectedRequests = [];
433 testRunner.registerHandler("/redirected", function(metadata) 773 this.registerHandler("/redirected", metadata =>
434 { 774 {
435 redirectedRequests.push(testRunner.getTimeOffset()); 775 redirectedRequests.push(this.getTimeOffset());
436 return [Cr.NS_OK, 200, "[Adblock]\n!Expires: 1day\nfoo\nbar"]; 776 return [Cr.NS_OK, 200, "[Adblock]\n!Expires: 1day\nfoo\nbar"];
437 }); 777 });
438 778
439 testRunner.runScheduledTasks(100); 779 return this.runScheduledTasks(100);
440 equal(FilterStorage.subscriptions[0].url, "http://example.com/redirected", " Valid redirect from fallback is followed"); 780 }).then(() =>
441 deepEqual(requests, [0 + initialDelay, 24 + initialDelay, 48 + initialDelay] , "Stop polling original URL after a valid redirect from fallback"); 781 {
442 deepEqual(redirectedRequests, [48 + initialDelay, 72 + initialDelay, 96 + in itialDelay], "Request new URL after a valid redirect from fallback"); 782 test.equal(FilterStorage.subscriptions[0].url, "http://example.com/redirecte d", "Valid redirect from fallback is followed");
783 test.deepEqual(requests, [0 + initialDelay, 24 + initialDelay, 48 + initialD elay], "Stop polling original URL after a valid redirect from fallback");
784 test.deepEqual(redirectedRequests, [48 + initialDelay, 72 + initialDelay, 96 + initialDelay], "Request new URL after a valid redirect from fallback");
443 785
444 // Checksum mismatch 786 // Checksum mismatch
445 787
446 testRunner.registerHandler("/subscription", function(metadata) 788 this.registerHandler("/subscription", metadata =>
447 { 789 {
448 return [Cr.NS_OK, 200, "[Adblock]\n! Checksum: wrong\nfoo\nbar"]; 790 return [Cr.NS_OK, 200, "[Adblock]\n! Checksum: wrong\nfoo\nbar"];
449 }); 791 });
450 792
451 subscription = Subscription.fromURL("http://example.com/subscription"); 793 subscription = Subscription.fromURL("http://example.com/subscription");
452 resetSubscription(subscription); 794 resetSubscription(subscription);
453 FilterStorage.removeSubscription(FilterStorage.subscriptions[0]); 795 FilterStorage.removeSubscription(FilterStorage.subscriptions[0]);
454 FilterStorage.addSubscription(subscription); 796 FilterStorage.addSubscription(subscription);
455 797
456 testRunner.runScheduledTasks(100); 798 return this.runScheduledTasks(100);
457 equal(FilterStorage.subscriptions[0].url, "http://example.com/redirected", " Wrong checksum produces fallback request"); 799 }).then(() =>
800 {
801 test.equal(FilterStorage.subscriptions[0].url, "http://example.com/redirecte d", "Wrong checksum produces fallback request");
458 802
459 // Redirect loop 803 // Redirect loop
460 804
461 testRunner.registerHandler("/subscription", function(metadata) 805 this.registerHandler("/subscription", metadata =>
462 { 806 {
463 return [Cr.NS_OK, 200, "[Adblock]\n! Redirect: http://example.com/subscrip tion2"]; 807 return [Cr.NS_OK, 200, "[Adblock]\n! Redirect: http://example.com/subscrip tion2"];
464 }); 808 });
465 testRunner.registerHandler("/subscription2", function(metadata, response) 809 this.registerHandler("/subscription2", metadata =>
466 { 810 {
467 return [Cr.NS_OK, 200, "[Adblock]\n! Redirect: http://example.com/subscrip tion"]; 811 return [Cr.NS_OK, 200, "[Adblock]\n! Redirect: http://example.com/subscrip tion"];
468 }); 812 });
469 813
470 subscription = Subscription.fromURL("http://example.com/subscription"); 814 subscription = Subscription.fromURL("http://example.com/subscription");
471 resetSubscription(subscription); 815 resetSubscription(subscription);
472 FilterStorage.removeSubscription(FilterStorage.subscriptions[0]); 816 FilterStorage.removeSubscription(FilterStorage.subscriptions[0]);
473 FilterStorage.addSubscription(subscription); 817 FilterStorage.addSubscription(subscription);
474 818
475 testRunner.runScheduledTasks(100); 819 return this.runScheduledTasks(100);
476 equal(FilterStorage.subscriptions[0].url, "http://example.com/redirected", " Fallback can still redirect even after a redirect loop"); 820 }).then(() =>
477 }); 821 {
478 822 test.equal(FilterStorage.subscriptions[0].url, "http://example.com/redirecte d", "Fallback can still redirect even after a redirect loop");
479 test("State fields", function() 823 }).catch(unexpectedError.bind(test)).then(() => test.done());
480 { 824 };
481 let subscription = Subscription.fromURL("http://example.com/subscription"); 825
482 FilterStorage.addSubscription(subscription); 826 exports.testStateFields = function(test)
483 827 {
484 testRunner.registerHandler("/subscription", function(metadata) 828 let subscription = Subscription.fromURL("http://example.com/subscription");
485 { 829 FilterStorage.addSubscription(subscription);
486 return [Cr.NS_OK, 200, "[Adblock]\n! Expires: 2 hours\nfoo\nbar"]; 830
487 }); 831 this.registerHandler("/subscription", metadata =>
488 832 {
489 let startTime = testRunner.currentTime; 833 return [Cr.NS_OK, 200, "[Adblock]\n! Expires: 2 hours\nfoo\nbar"];
490 testRunner.runScheduledTasks(2); 834 });
491 835
492 equal(subscription.downloadStatus, "synchronize_ok", "downloadStatus after s uccessful download"); 836 let startTime = this.currentTime;
493 equal(subscription.lastDownload * MILLIS_IN_SECOND, startTime + initialDela y * MILLIS_IN_HOUR, "lastDownload after successful download"); 837 this.runScheduledTasks(2).then(() =>
494 equal(subscription.lastSuccess * MILLIS_IN_SECOND, startTime + initialDelay * MILLIS_IN_HOUR, "lastSuccess after successful download"); 838 {
495 equal(subscription.lastCheck * MILLIS_IN_SECOND, startTime + (1 + initialDe lay) * MILLIS_IN_HOUR, "lastCheck after successful download"); 839 test.equal(subscription.downloadStatus, "synchronize_ok", "downloadStatus af ter successful download");
496 equal(subscription.errors, 0, "errors after successful download"); 840 test.equal(subscription.lastDownload * MILLIS_IN_SECOND, startTime + initia lDelay * MILLIS_IN_HOUR, "lastDownload after successful download");
497 841 test.equal(subscription.lastSuccess * MILLIS_IN_SECOND, startTime + initial Delay * MILLIS_IN_HOUR, "lastSuccess after successful download");
498 testRunner.registerHandler("/subscription", function(metadata) 842 test.equal(subscription.lastCheck * MILLIS_IN_SECOND, startTime + (1 + init ialDelay) * MILLIS_IN_HOUR, "lastCheck after successful download");
843 test.equal(subscription.errors, 0, "errors after successful download");
844
845 this.registerHandler("/subscription", metadata =>
499 { 846 {
500 return [Cr.NS_ERROR_FAILURE, 0, ""]; 847 return [Cr.NS_ERROR_FAILURE, 0, ""];
501 }); 848 });
502 849
503 testRunner.runScheduledTasks(2); 850 return this.runScheduledTasks(2);
504 851 }).then(() =>
505 equal(subscription.downloadStatus, "synchronize_connection_error", "download Status after connection error"); 852 {
506 equal(subscription.lastDownload * MILLIS_IN_SECOND, startTime + (2 + initia lDelay) * MILLIS_IN_HOUR, "lastDownload after connection error"); 853 test.equal(subscription.downloadStatus, "synchronize_connection_error", "dow nloadStatus after connection error");
507 equal(subscription.lastSuccess * MILLIS_IN_SECOND, startTime + initialDelay * MILLIS_IN_HOUR, "lastSuccess after connection error"); 854 test.equal(subscription.lastDownload * MILLIS_IN_SECOND, startTime + (2 + i nitialDelay) * MILLIS_IN_HOUR, "lastDownload after connection error");
508 equal(subscription.lastCheck * MILLIS_IN_SECOND, startTime + (3 + initialDel ay) * MILLIS_IN_HOUR, "lastCheck after connection error"); 855 test.equal(subscription.lastSuccess * MILLIS_IN_SECOND, startTime + initialD elay * MILLIS_IN_HOUR, "lastSuccess after connection error");
509 equal(subscription.errors, 1, "errors after connection error"); 856 test.equal(subscription.lastCheck * MILLIS_IN_SECOND, startTime + (3 + initi alDelay) * MILLIS_IN_HOUR, "lastCheck after connection error");
510 857 test.equal(subscription.errors, 1, "errors after connection error");
511 testRunner.registerHandler("/subscription", function(metadata) 858
859 this.registerHandler("/subscription", metadata =>
512 { 860 {
513 return [Cr.NS_OK, 404, ""]; 861 return [Cr.NS_OK, 404, ""];
514 }); 862 });
515 863
516 testRunner.runScheduledTasks(24); 864 return this.runScheduledTasks(24);
517 865 }).then(() =>
518 equal(subscription.downloadStatus, "synchronize_connection_error", "download Status after download error"); 866 {
519 equal(subscription.lastDownload * MILLIS_IN_SECOND, startTime + (26 + initia lDelay) * MILLIS_IN_HOUR, "lastDownload after download error"); 867 test.equal(subscription.downloadStatus, "synchronize_connection_error", "dow nloadStatus after download error");
520 equal(subscription.lastSuccess * MILLIS_IN_SECOND, startTime + initialDelay * MILLIS_IN_HOUR, "lastSuccess after download error"); 868 test.equal(subscription.lastDownload * MILLIS_IN_SECOND, startTime + (26 + i nitialDelay) * MILLIS_IN_HOUR, "lastDownload after download error");
521 equal(subscription.lastCheck * MILLIS_IN_SECOND, startTime + (27 + initialDe lay) * MILLIS_IN_HOUR, "lastCheck after download error"); 869 test.equal(subscription.lastSuccess * MILLIS_IN_SECOND, startTime + initialD elay * MILLIS_IN_HOUR, "lastSuccess after download error");
522 equal(subscription.errors, 2, "errors after download error"); 870 test.equal(subscription.lastCheck * MILLIS_IN_SECOND, startTime + (27 + init ialDelay) * MILLIS_IN_HOUR, "lastCheck after download error");
523 }); 871 test.equal(subscription.errors, 2, "errors after download error");
524 })(); 872 }).catch(unexpectedError.bind(test)).then(() => test.done());
873 };
OLDNEW
« test/_common.js ('K') | « test/stub-modules/utils.js ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld