| OLD | NEW | 
|---|
|  | (Empty) | 
| 1 (function() |  | 
| 2 { |  | 
| 3   let testRunner = null; |  | 
| 4   let requestHandlers = null; |  | 
| 5   let randomResult = 0.5; |  | 
| 6 |  | 
| 7   module("Synchronizer", { |  | 
| 8     setup: function() |  | 
| 9     { |  | 
| 10       testRunner = this; |  | 
| 11 |  | 
| 12       prepareFilterComponents.call(this); |  | 
| 13       preparePrefs.call(this); |  | 
| 14 |  | 
| 15       Synchronizer.init(); |  | 
| 16 |  | 
| 17       setupVirtualTime.call(this, function(wrapTimer) |  | 
| 18       { |  | 
| 19         let SynchronizerModule = getModuleGlobal("synchronizer"); |  | 
| 20         SynchronizerModule.downloader._timer = wrapTimer(SynchronizerModule.down
     loader._timer); |  | 
| 21       }, "synchronizer", "downloader"); |  | 
| 22       setupVirtualXMLHttp.call(this, "synchronizer", "downloader"); |  | 
| 23 |  | 
| 24       // Replace Math.random() function |  | 
| 25       let DownloaderGlobal = Cu.getGlobalForObject(getModuleGlobal("downloader")
     ); |  | 
| 26       this._origRandom = DownloaderGlobal.Math.random; |  | 
| 27       DownloaderGlobal.Math.random = () => randomResult; |  | 
| 28       randomResult = 0.5; |  | 
| 29     }, |  | 
| 30 |  | 
| 31     teardown: function() |  | 
| 32     { |  | 
| 33       restoreFilterComponents.call(this); |  | 
| 34       restorePrefs.call(this); |  | 
| 35       restoreVirtualTime.call(this); |  | 
| 36       restoreVirtualXMLHttp.call(this); |  | 
| 37 |  | 
| 38       if (this._origRandom) |  | 
| 39       { |  | 
| 40         let DownloaderGlobal = Cu.getGlobalForObject(getModuleGlobal("downloader
     ")); |  | 
| 41         DownloaderGlobal.Math.random = this._origRandom; |  | 
| 42         delete this._origRandom; |  | 
| 43       } |  | 
| 44 |  | 
| 45       Synchronizer.init(); |  | 
| 46     } |  | 
| 47   }); |  | 
| 48 |  | 
| 49   function resetSubscription(subscription) |  | 
| 50   { |  | 
| 51     FilterStorage.updateSubscriptionFilters(subscription, []); |  | 
| 52     subscription.lastCheck =  subscription.lastDownload = |  | 
| 53       subscription.version = subscription.lastSuccess = |  | 
| 54       subscription.expires = subscription.softExpiration = 0; |  | 
| 55     subscription.title = ""; |  | 
| 56     subscription.homepage = null; |  | 
| 57     subscription.errors = 0; |  | 
| 58     subscription.downloadStatus = null; |  | 
| 59     subscription.requiredVersion = null; |  | 
| 60   } |  | 
| 61 |  | 
| 62   let initialDelay = 1 / 60; |  | 
| 63 |  | 
| 64   test("Downloads of one subscription", function() |  | 
| 65   { |  | 
| 66     let subscription = Subscription.fromURL("http://example.com/subscription"); |  | 
| 67     FilterStorage.addSubscription(subscription); |  | 
| 68 |  | 
| 69     let requests = []; |  | 
| 70     testRunner.registerHandler("/subscription", function(metadata) |  | 
| 71     { |  | 
| 72       requests.push([testRunner.getTimeOffset(), metadata.method, metadata.path]
     ); |  | 
| 73       return [Cr.NS_OK, 200, "[Adblock]\n! ExPiREs: 1day\nfoo\nbar"]; |  | 
| 74     }); |  | 
| 75 |  | 
| 76     testRunner.runScheduledTasks(50); |  | 
| 77     deepEqual(requests, [ |  | 
| 78       [0 + initialDelay, "GET", "/subscription"], |  | 
| 79       [24 + initialDelay, "GET", "/subscription"], |  | 
| 80       [48 + initialDelay, "GET", "/subscription"], |  | 
| 81     ], "Requests after 50 hours"); |  | 
| 82   }); |  | 
| 83 |  | 
| 84   test("Downloads of two subscriptions", function() |  | 
| 85   { |  | 
| 86     let subscription1 = Subscription.fromURL("http://example.com/subscription1")
     ; |  | 
| 87     FilterStorage.addSubscription(subscription1); |  | 
| 88 |  | 
| 89     let subscription2 = Subscription.fromURL("http://example.com/subscription2")
     ; |  | 
| 90     subscription2.expires = |  | 
| 91       subscription2.softExpiration = |  | 
| 92       (testRunner.currentTime + 2 * MILLIS_IN_HOUR) / MILLIS_IN_SECOND; |  | 
| 93     FilterStorage.addSubscription(subscription2); |  | 
| 94 |  | 
| 95     let requests = []; |  | 
| 96     function handler(metadata) |  | 
| 97     { |  | 
| 98       requests.push([testRunner.getTimeOffset(), metadata.method, metadata.path]
     ); |  | 
| 99       return [Cr.NS_OK, 200, "[Adblock]\n! ExPiREs: 1day\nfoo\nbar"]; |  | 
| 100     } |  | 
| 101 |  | 
| 102     testRunner.registerHandler("/subscription1", handler); |  | 
| 103     testRunner.registerHandler("/subscription2", handler); |  | 
| 104 |  | 
| 105     testRunner.runScheduledTasks(55); |  | 
| 106     deepEqual(requests, [ |  | 
| 107       [0 + initialDelay, "GET", "/subscription1"], |  | 
| 108       [2 + initialDelay, "GET", "/subscription2"], |  | 
| 109       [24 + initialDelay, "GET", "/subscription1"], |  | 
| 110       [26 + initialDelay, "GET", "/subscription2"], |  | 
| 111       [48 + initialDelay, "GET", "/subscription1"], |  | 
| 112       [50 + initialDelay, "GET", "/subscription2"], |  | 
| 113     ], "Requests after 55 hours"); |  | 
| 114   }); |  | 
| 115 |  | 
| 116   test("Download result, various subscription headers", function() |  | 
| 117   { |  | 
| 118     let test; |  | 
| 119     let subscription = Subscription.fromURL("http://example.com/subscription"); |  | 
| 120     FilterStorage.addSubscription(subscription); |  | 
| 121 |  | 
| 122     testRunner.registerHandler("/subscription", function(metadata) |  | 
| 123     { |  | 
| 124       return [Cr.NS_OK, 200, test.header + "\n!Expires: 8 hours\nfoo\n!bar\n\n@@
     bas\n#bam"]; |  | 
| 125     }); |  | 
| 126 |  | 
| 127     let tests = [ |  | 
| 128       {header: "[Adblock]", downloadStatus: "synchronize_ok", requiredVersion: n
     ull}, |  | 
| 129       {header: "[Adblock Plus]", downloadStatus: "synchronize_ok", requiredVersi
     on: null}, |  | 
| 130       {header: "(something)[Adblock]", downloadStatus: "synchronize_ok", require
     dVersion: null}, |  | 
| 131       {header: "[Adblock Plus 0.0.1]", downloadStatus: "synchronize_ok", require
     dVersion: "0.0.1"}, |  | 
| 132       {header: "[Adblock Plus 99.9]", downloadStatus: "synchronize_ok", required
     Version: "99.9"}, |  | 
| 133       {header: "[Foo]", downloadStatus: "synchronize_invalid_data", requiredVers
     ion: null} |  | 
| 134     ]; |  | 
| 135     for (test of tests) |  | 
| 136     { |  | 
| 137       resetSubscription(subscription) |  | 
| 138       testRunner.runScheduledTasks(2); |  | 
| 139 |  | 
| 140       equal(subscription.downloadStatus, test.downloadStatus, "Download status f
     or " + test.header) |  | 
| 141       equal(subscription.requiredVersion, test.requiredVersion, "Required versio
     n for " + test.header) |  | 
| 142 |  | 
| 143       if (test.downloadStatus == "synchronize_ok") |  | 
| 144       { |  | 
| 145         deepEqual(subscription.filters, [ |  | 
| 146           Filter.fromText("foo"), |  | 
| 147           Filter.fromText("!bar"), |  | 
| 148           Filter.fromText("@@bas"), |  | 
| 149           Filter.fromText("#bam"), |  | 
| 150         ], "Resulting subscription filters for " + test.header); |  | 
| 151       } |  | 
| 152       else |  | 
| 153       { |  | 
| 154         deepEqual(subscription.filters, [ |  | 
| 155         ], "Resulting subscription filters for " + test.header); |  | 
| 156       } |  | 
| 157     } |  | 
| 158   }) |  | 
| 159 |  | 
| 160   test("Automatic updates disabled", function() |  | 
| 161   { |  | 
| 162     Prefs.subscriptions_autoupdate = false; |  | 
| 163 |  | 
| 164     let subscription = Subscription.fromURL("http://example.com/subscription"); |  | 
| 165     FilterStorage.addSubscription(subscription); |  | 
| 166 |  | 
| 167     let requests = 0; |  | 
| 168     testRunner.registerHandler("/subscription", function(metadata) |  | 
| 169     { |  | 
| 170       requests++; |  | 
| 171       throw new Error("Unexpected request"); |  | 
| 172     }); |  | 
| 173 |  | 
| 174     testRunner.runScheduledTasks(50); |  | 
| 175     equal(requests, 0, "Request count"); |  | 
| 176   }); |  | 
| 177 |  | 
| 178   test("Expiration time", function() |  | 
| 179   { |  | 
| 180     let subscription = Subscription.fromURL("http://example.com/subscription"); |  | 
| 181     FilterStorage.addSubscription(subscription); |  | 
| 182 |  | 
| 183     let test; |  | 
| 184     let requests = []; |  | 
| 185     testRunner.registerHandler("/subscription", function(metadata) |  | 
| 186     { |  | 
| 187       requests.push(testRunner.getTimeOffset()); |  | 
| 188       return [Cr.NS_OK, 200, "[Adblock]\nfoo\n!Expires: " + test.expiration + "\
     nbar"]; |  | 
| 189     }); |  | 
| 190 |  | 
| 191     let tests = [ |  | 
| 192       { |  | 
| 193         expiration: "default", |  | 
| 194         randomResult: 0.5, |  | 
| 195         requests: [0 + initialDelay, 5 * 24 +  initialDelay] |  | 
| 196       }, |  | 
| 197       { |  | 
| 198         expiration: "1 hours",  // Minimal expiration interval |  | 
| 199         randomResult: 0.5, |  | 
| 200         requests: [0 + initialDelay, 1 + initialDelay, 2 + initialDelay, 3 + ini
     tialDelay] |  | 
| 201       }, |  | 
| 202       { |  | 
| 203         expiration: "26 hours", |  | 
| 204         randomResult: 0.5, |  | 
| 205         requests: [0 + initialDelay, 26 + initialDelay] |  | 
| 206       }, |  | 
| 207       { |  | 
| 208         expiration: "2 days", |  | 
| 209         randomResult: 0.5, |  | 
| 210         requests: [0 + initialDelay, 48 + initialDelay] |  | 
| 211       }, |  | 
| 212       { |  | 
| 213         expiration: "20 days",  // Too large, will be corrected |  | 
| 214         randomResult: 0.5, |  | 
| 215         requests: [0 + initialDelay, 14 * 24 + initialDelay] |  | 
| 216       }, |  | 
| 217       { |  | 
| 218         expiration: "35 hours", |  | 
| 219         randomResult: 0,        // Changes interval by factor 0.8 |  | 
| 220         requests: [0 + initialDelay, 28 + initialDelay] |  | 
| 221       }, |  | 
| 222       { |  | 
| 223         expiration: "35 hours", |  | 
| 224         randomResult: 1,        // Changes interval by factor 1.2 |  | 
| 225         requests: [0 + initialDelay, 42 + initialDelay] |  | 
| 226       }, |  | 
| 227       { |  | 
| 228         expiration: "35 hours", |  | 
| 229         randomResult: 0.25,     // Changes interval by factor 0.9 |  | 
| 230         requests: [0 + initialDelay, 32 + initialDelay] |  | 
| 231       }, |  | 
| 232       { |  | 
| 233         expiration: "40 hours", |  | 
| 234         randomResult: 0.5, |  | 
| 235         skipAfter: 5 + initialDelay, |  | 
| 236         skip: 10,               // Short break should not increase soft expirati
     on |  | 
| 237         requests: [0 + initialDelay, 40 + initialDelay] |  | 
| 238       }, |  | 
| 239       { |  | 
| 240         expiration: "40 hours", |  | 
| 241         randomResult: 0.5, |  | 
| 242         skipAfter: 5 + initialDelay, |  | 
| 243         skip: 30,               // Long break should increase soft expiration |  | 
| 244         requests: [0 + initialDelay, 70 + initialDelay] |  | 
| 245       }, |  | 
| 246       { |  | 
| 247         expiration: "40 hours", |  | 
| 248         randomResult: 0.5, |  | 
| 249         skipAfter: 5 + initialDelay, |  | 
| 250         skip: 80,               // Hitting hard expiration, immediate download |  | 
| 251         requests: [0 + initialDelay, 85 + initialDelay] |  | 
| 252       } |  | 
| 253     ] |  | 
| 254 |  | 
| 255     for (test of tests) |  | 
| 256     { |  | 
| 257       requests = []; |  | 
| 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(); |  | 
| 331       deepEqual(subscription.filters, [Filter.fromText("foo"), Filter.fromText("
     bar")], "Special comment not added to filters"); |  | 
| 332     } |  | 
| 333   }); |  | 
| 334 |  | 
| 335   test("Redirects", function() |  | 
| 336   { |  | 
| 337     let subscription = Subscription.fromURL("http://example.com/subscription"); |  | 
| 338     FilterStorage.addSubscription(subscription); |  | 
| 339 |  | 
| 340     testRunner.registerHandler("/subscription", function(metadata) |  | 
| 341     { |  | 
| 342       return [Cr.NS_OK, 200, "[Adblock]\nfoo\n!Redirect: http://example.com/redi
     rected\nbar"]; |  | 
| 343     }); |  | 
| 344 |  | 
| 345     testRunner.runScheduledTasks(30); |  | 
| 346     equal(FilterStorage.subscriptions[0], subscription, "Invalid redirect ignore
     d"); |  | 
| 347     equal(subscription.downloadStatus, "synchronize_connection_error", "Connecti
     on error recorded"); |  | 
| 348     equal(subscription.errors, 2, "Number of download errors"); |  | 
| 349 |  | 
| 350     let requests = []; |  | 
| 351     testRunner.registerHandler("/redirected", function(metadata) |  | 
| 352     { |  | 
| 353       requests.push(testRunner.getTimeOffset()); |  | 
| 354       return [Cr.NS_OK, 200, "[Adblock]\nfoo\n! Expires: 8 hours\nbar"]; |  | 
| 355     }); |  | 
| 356 |  | 
| 357     resetSubscription(subscription); |  | 
| 358     testRunner.runScheduledTasks(15); |  | 
| 359     equal(FilterStorage.subscriptions[0].url, "http://example.com/redirected", "
     Redirect followed"); |  | 
| 360     deepEqual(requests, [0 + initialDelay, 8 + initialDelay], "Resulting request
     s"); |  | 
| 361 |  | 
| 362     testRunner.registerHandler("/redirected", function(metadata) |  | 
| 363     { |  | 
| 364       return [Cr.NS_OK, 200, "[Adblock]\nfoo\n!Redirect: http://example.com/subs
     cription\nbar"]; |  | 
| 365     }) |  | 
| 366 |  | 
| 367     subscription = Subscription.fromURL("http://example.com/subscription"); |  | 
| 368     resetSubscription(subscription); |  | 
| 369     FilterStorage.removeSubscription(FilterStorage.subscriptions[0]); |  | 
| 370     FilterStorage.addSubscription(subscription); |  | 
| 371 |  | 
| 372     testRunner.runScheduledTasks(2); |  | 
| 373     equal(FilterStorage.subscriptions[0], subscription, "Redirect not followed o
     n redirect loop"); |  | 
| 374     equal(subscription.downloadStatus, "synchronize_connection_error", "Download
      status after redirect loop"); |  | 
| 375   }); |  | 
| 376 |  | 
| 377   test("Fallback", function() |  | 
| 378   { |  | 
| 379     Prefs.subscriptions_fallbackerrors = 3; |  | 
| 380     Prefs.subscriptions_fallbackurl = "http://example.com/fallback?%SUBSCRIPTION
     %&%CHANNELSTATUS%&%RESPONSESTATUS%"; |  | 
| 381 |  | 
| 382     let subscription = Subscription.fromURL("http://example.com/subscription"); |  | 
| 383     FilterStorage.addSubscription(subscription); |  | 
| 384 |  | 
| 385     // No valid response from fallback |  | 
| 386 |  | 
| 387     let requests = []; |  | 
| 388     testRunner.registerHandler("/subscription", function(metadata) |  | 
| 389     { |  | 
| 390       requests.push(testRunner.getTimeOffset()); |  | 
| 391       return [Cr.NS_OK, 404, ""]; |  | 
| 392     }); |  | 
| 393 |  | 
| 394     testRunner.runScheduledTasks(100); |  | 
| 395     deepEqual(requests, [0 + initialDelay, 24 + initialDelay, 48 + initialDelay,
      72 + initialDelay, 96 + initialDelay], "Continue trying if the fallback doesn't
      respond"); |  | 
| 396 |  | 
| 397     // Fallback giving "Gone" response |  | 
| 398 |  | 
| 399     resetSubscription(subscription); |  | 
| 400     requests = []; |  | 
| 401     fallbackParams = null; |  | 
| 402     testRunner.registerHandler("/fallback", function(metadata) |  | 
| 403     { |  | 
| 404       fallbackParams = decodeURIComponent(metadata.queryString); |  | 
| 405       return [Cr.NS_OK, 200, "410 Gone"]; |  | 
| 406     }); |  | 
| 407 |  | 
| 408     testRunner.runScheduledTasks(100); |  | 
| 409     deepEqual(requests, [0 + initialDelay, 24 + initialDelay, 48 + initialDelay]
     , "Stop trying if the fallback responds with Gone"); |  | 
| 410     equal(fallbackParams, "http://example.com/subscription&0&404", "Fallback arg
     uments"); |  | 
| 411 |  | 
| 412     // Fallback redirecting to a missing file |  | 
| 413 |  | 
| 414     subscription = Subscription.fromURL("http://example.com/subscription"); |  | 
| 415     resetSubscription(subscription); |  | 
| 416     FilterStorage.removeSubscription(FilterStorage.subscriptions[0]); |  | 
| 417     FilterStorage.addSubscription(subscription); |  | 
| 418     requests = []; |  | 
| 419 |  | 
| 420     testRunner.registerHandler("/fallback", function(metadata) |  | 
| 421     { |  | 
| 422       return [Cr.NS_OK, 200, "301 http://example.com/redirected"]; |  | 
| 423     }); |  | 
| 424     testRunner.runScheduledTasks(100); |  | 
| 425     equal(FilterStorage.subscriptions[0].url, "http://example.com/subscription",
      "Ignore invalid redirect from fallback"); |  | 
| 426     deepEqual(requests, [0 + initialDelay, 24 + initialDelay, 48 + initialDelay,
      72 + initialDelay, 96 + initialDelay], "Requests not affected by invalid redire
     ct"); |  | 
| 427 |  | 
| 428     // Fallback redirecting to an existing file |  | 
| 429 |  | 
| 430     resetSubscription(subscription); |  | 
| 431     requests = []; |  | 
| 432     let redirectedRequests = []; |  | 
| 433     testRunner.registerHandler("/redirected", function(metadata) |  | 
| 434     { |  | 
| 435       redirectedRequests.push(testRunner.getTimeOffset()); |  | 
| 436       return [Cr.NS_OK, 200, "[Adblock]\n!Expires: 1day\nfoo\nbar"]; |  | 
| 437     }); |  | 
| 438 |  | 
| 439     testRunner.runScheduledTasks(100); |  | 
| 440     equal(FilterStorage.subscriptions[0].url, "http://example.com/redirected", "
     Valid redirect from fallback is followed"); |  | 
| 441     deepEqual(requests, [0 + initialDelay, 24 + initialDelay, 48 + initialDelay]
     , "Stop polling original URL after a valid redirect from fallback"); |  | 
| 442     deepEqual(redirectedRequests, [48 + initialDelay, 72 + initialDelay, 96 + in
     itialDelay], "Request new URL after a valid redirect from fallback"); |  | 
| 443 |  | 
| 444     // Checksum mismatch |  | 
| 445 |  | 
| 446     testRunner.registerHandler("/subscription", function(metadata) |  | 
| 447     { |  | 
| 448       return [Cr.NS_OK, 200, "[Adblock]\n! Checksum: wrong\nfoo\nbar"]; |  | 
| 449     }); |  | 
| 450 |  | 
| 451     subscription = Subscription.fromURL("http://example.com/subscription"); |  | 
| 452     resetSubscription(subscription); |  | 
| 453     FilterStorage.removeSubscription(FilterStorage.subscriptions[0]); |  | 
| 454     FilterStorage.addSubscription(subscription); |  | 
| 455 |  | 
| 456     testRunner.runScheduledTasks(100); |  | 
| 457     equal(FilterStorage.subscriptions[0].url, "http://example.com/redirected", "
     Wrong checksum produces fallback request"); |  | 
| 458 |  | 
| 459     // Redirect loop |  | 
| 460 |  | 
| 461     testRunner.registerHandler("/subscription", function(metadata) |  | 
| 462     { |  | 
| 463       return [Cr.NS_OK, 200, "[Adblock]\n! Redirect: http://example.com/subscrip
     tion2"]; |  | 
| 464     }); |  | 
| 465     testRunner.registerHandler("/subscription2", function(metadata, response) |  | 
| 466     { |  | 
| 467       return [Cr.NS_OK, 200, "[Adblock]\n! Redirect: http://example.com/subscrip
     tion"]; |  | 
| 468     }); |  | 
| 469 |  | 
| 470     subscription = Subscription.fromURL("http://example.com/subscription"); |  | 
| 471     resetSubscription(subscription); |  | 
| 472     FilterStorage.removeSubscription(FilterStorage.subscriptions[0]); |  | 
| 473     FilterStorage.addSubscription(subscription); |  | 
| 474 |  | 
| 475     testRunner.runScheduledTasks(100); |  | 
| 476     equal(FilterStorage.subscriptions[0].url, "http://example.com/redirected", "
     Fallback can still redirect even after a redirect loop"); |  | 
| 477   }); |  | 
| 478 |  | 
| 479   test("State fields", function() |  | 
| 480   { |  | 
| 481     let subscription = Subscription.fromURL("http://example.com/subscription"); |  | 
| 482     FilterStorage.addSubscription(subscription); |  | 
| 483 |  | 
| 484     testRunner.registerHandler("/subscription", function(metadata) |  | 
| 485     { |  | 
| 486       return [Cr.NS_OK, 200, "[Adblock]\n! Expires: 2 hours\nfoo\nbar"]; |  | 
| 487     }); |  | 
| 488 |  | 
| 489     let startTime = testRunner.currentTime; |  | 
| 490     testRunner.runScheduledTasks(2); |  | 
| 491 |  | 
| 492     equal(subscription.downloadStatus, "synchronize_ok", "downloadStatus after s
     uccessful download"); |  | 
| 493     equal(subscription.lastDownload * MILLIS_IN_SECOND, startTime +  initialDela
     y * MILLIS_IN_HOUR, "lastDownload after successful download"); |  | 
| 494     equal(subscription.lastSuccess * MILLIS_IN_SECOND, startTime +  initialDelay
      * MILLIS_IN_HOUR, "lastSuccess after successful download"); |  | 
| 495     equal(subscription.lastCheck * MILLIS_IN_SECOND, startTime + (1 +  initialDe
     lay) * MILLIS_IN_HOUR, "lastCheck after successful download"); |  | 
| 496     equal(subscription.errors, 0, "errors after successful download"); |  | 
| 497 |  | 
| 498     testRunner.registerHandler("/subscription", function(metadata) |  | 
| 499     { |  | 
| 500       return [Cr.NS_ERROR_FAILURE, 0, ""]; |  | 
| 501     }); |  | 
| 502 |  | 
| 503     testRunner.runScheduledTasks(2); |  | 
| 504 |  | 
| 505     equal(subscription.downloadStatus, "synchronize_connection_error", "download
     Status after connection error"); |  | 
| 506     equal(subscription.lastDownload * MILLIS_IN_SECOND, startTime + (2 +  initia
     lDelay) * MILLIS_IN_HOUR, "lastDownload after connection error"); |  | 
| 507     equal(subscription.lastSuccess * MILLIS_IN_SECOND, startTime + initialDelay 
     * MILLIS_IN_HOUR, "lastSuccess after connection error"); |  | 
| 508     equal(subscription.lastCheck * MILLIS_IN_SECOND, startTime + (3 + initialDel
     ay) * MILLIS_IN_HOUR, "lastCheck after connection error"); |  | 
| 509     equal(subscription.errors, 1, "errors after connection error"); |  | 
| 510 |  | 
| 511     testRunner.registerHandler("/subscription", function(metadata) |  | 
| 512     { |  | 
| 513       return [Cr.NS_OK, 404, ""]; |  | 
| 514     }); |  | 
| 515 |  | 
| 516     testRunner.runScheduledTasks(24); |  | 
| 517 |  | 
| 518     equal(subscription.downloadStatus, "synchronize_connection_error", "download
     Status after download error"); |  | 
| 519     equal(subscription.lastDownload * MILLIS_IN_SECOND, startTime + (26 + initia
     lDelay) * MILLIS_IN_HOUR, "lastDownload after download error"); |  | 
| 520     equal(subscription.lastSuccess * MILLIS_IN_SECOND, startTime + initialDelay 
     * MILLIS_IN_HOUR, "lastSuccess after download error"); |  | 
| 521     equal(subscription.lastCheck * MILLIS_IN_SECOND, startTime + (27 + initialDe
     lay) * MILLIS_IN_HOUR, "lastCheck after download error"); |  | 
| 522     equal(subscription.errors, 2, "errors after download error"); |  | 
| 523   }); |  | 
| 524 })(); |  | 
| OLD | NEW | 
|---|