| OLD | NEW |
| 1 /* | 1 /* |
| 2 * This file is part of Adblock Plus <https://adblockplus.org/>, | 2 * This file is part of Adblock Plus <https://adblockplus.org/>, |
| 3 * Copyright (C) 2006-present eyeo GmbH | 3 * Copyright (C) 2006-present eyeo GmbH |
| 4 * | 4 * |
| 5 * Adblock Plus is free software: you can redistribute it and/or modify | 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 | 6 * it under the terms of the GNU General Public License version 3 as |
| 7 * published by the Free Software Foundation. | 7 * published by the Free Software Foundation. |
| 8 * | 8 * |
| 9 * Adblock Plus is distributed in the hope that it will be useful, | 9 * Adblock Plus is distributed in the hope that it will be useful, |
| 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of | 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 12 * GNU General Public License for more details. | 12 * GNU General Public License for more details. |
| 13 * | 13 * |
| 14 * You should have received a copy of the GNU General Public License | 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/>. | 15 * along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>. |
| 16 */ | 16 */ |
| 17 | 17 |
| 18 "use strict"; | 18 "use strict"; |
| 19 | 19 |
| 20 const assert = require("assert"); |
| 20 let { | 21 let { |
| 21 createSandbox, setupTimerAndFetch, setupRandomResult, unexpectedError, | 22 createSandbox, setupTimerAndFetch, setupRandomResult, |
| 22 MILLIS_IN_SECOND, MILLIS_IN_HOUR | 23 MILLIS_IN_SECOND, MILLIS_IN_HOUR |
| 23 } = require("./_common"); | 24 } = require("./_common"); |
| 24 | 25 |
| 25 let filterStorage = null; | 26 let filterStorage = null; |
| 26 let Prefs = null; | 27 let Prefs = null; |
| 27 let Subscription = null; | 28 let Subscription = null; |
| 28 | 29 |
| 29 exports.setUp = function(callback) | 30 describe("Synchronizer", () => |
| 30 { | 31 { |
| 31 let globals = Object.assign({}, setupTimerAndFetch.call(this), | 32 let runner = {}; |
| 32 setupRandomResult.call(this)); | 33 |
| 33 | 34 beforeEach(() => |
| 34 let sandboxedRequire = createSandbox({globals}); | 35 { |
| 35 ( | 36 runner = {}; |
| 36 {filterStorage} = sandboxedRequire("../lib/filterStorage"), | 37 let globals = Object.assign({}, setupTimerAndFetch.call(runner), |
| 37 {Prefs} = sandboxedRequire("./stub-modules/prefs"), | 38 setupRandomResult.call(runner)); |
| 38 {Subscription} = sandboxedRequire("../lib/subscriptionClasses"), | 39 |
| 39 sandboxedRequire("../lib/synchronizer") | 40 let sandboxedRequire = createSandbox({globals}); |
| 40 ); | 41 ( |
| 41 | 42 {filterStorage} = sandboxedRequire("../lib/filterStorage"), |
| 42 callback(); | 43 {Prefs} = sandboxedRequire("./stub-modules/prefs"), |
| 43 }; | 44 {Subscription} = sandboxedRequire("../lib/subscriptionClasses"), |
| 44 | 45 sandboxedRequire("../lib/synchronizer") |
| 45 function resetSubscription(subscription) | 46 ); |
| 46 { | 47 }); |
| 47 filterStorage.updateSubscriptionFilters(subscription, []); | 48 |
| 48 subscription.lastCheck = subscription.lastDownload = | 49 function resetSubscription(subscription) |
| 49 subscription.version = subscription.lastSuccess = | 50 { |
| 50 subscription.expires = subscription.softExpiration = 0; | 51 filterStorage.updateSubscriptionFilters(subscription, []); |
| 51 subscription.title = ""; | 52 subscription.lastCheck = subscription.lastDownload = |
| 52 subscription.homepage = null; | 53 subscription.version = subscription.lastSuccess = |
| 53 subscription.errors = 0; | 54 subscription.expires = subscription.softExpiration = 0; |
| 54 subscription.downloadStatus = null; | 55 subscription.title = ""; |
| 55 subscription.requiredVersion = null; | 56 subscription.homepage = null; |
| 56 } | 57 subscription.errors = 0; |
| 57 | 58 subscription.downloadStatus = null; |
| 58 let initialDelay = 1 / 60; | 59 subscription.requiredVersion = null; |
| 59 | 60 } |
| 60 exports.testOneSubscriptionDownloads = function(test) | 61 |
| 61 { | 62 let initialDelay = 1 / 60; |
| 62 let subscription = Subscription.fromURL("http://example.com/subscription"); | 63 |
| 63 filterStorage.addSubscription(subscription); | 64 describe("Downloads", () => |
| 64 | 65 { |
| 65 let requests = []; | 66 it("One Subscription", () => |
| 66 this.registerHandler("/subscription", metadata => | 67 { |
| 67 { | 68 let subscription = Subscription.fromURL("http://example.com/subscription")
; |
| 68 requests.push([this.getTimeOffset(), metadata.method, metadata.path]); | 69 filterStorage.addSubscription(subscription); |
| 69 return [200, "[Adblock]\n! ExPiREs: 1day\nfoo\nbar"]; | 70 |
| 70 }); | 71 let requests = []; |
| 71 | 72 runner.registerHandler("/subscription", metadata => |
| 72 this.runScheduledTasks(50).then(() => | 73 { |
| 73 { | 74 requests.push([runner.getTimeOffset(), metadata.method, metadata.path]); |
| 74 test.deepEqual(requests, [ | 75 return [200, "[Adblock]\n! ExPiREs: 1day\nfoo\nbar"]; |
| 75 [0 + initialDelay, "GET", "/subscription"], | 76 }); |
| 76 [24 + initialDelay, "GET", "/subscription"], | 77 |
| 77 [48 + initialDelay, "GET", "/subscription"] | 78 return runner.runScheduledTasks(50).then(() => |
| 78 ], "Requests after 50 hours"); | 79 { |
| 79 }).catch(unexpectedError.bind(test)).then(() => test.done()); | 80 assert.deepEqual(requests, [ |
| 80 }; | 81 [0 + initialDelay, "GET", "/subscription"], |
| 81 | 82 [24 + initialDelay, "GET", "/subscription"], |
| 82 exports.testTwoSubscriptionsDownloads = function(test) | 83 [48 + initialDelay, "GET", "/subscription"] |
| 83 { | 84 ], "Requests after 50 hours"); |
| 84 let subscription1 = Subscription.fromURL("http://example.com/subscription1"); | 85 }); |
| 85 filterStorage.addSubscription(subscription1); | 86 }); |
| 86 | 87 |
| 87 let subscription2 = Subscription.fromURL("http://example.com/subscription2"); | 88 it("Two Subscriptions", () => |
| 88 subscription2.expires = | 89 { |
| 89 subscription2.softExpiration = | 90 let subscription1 = Subscription.fromURL("http://example.com/subscription1
"); |
| 90 (this.currentTime + 2 * MILLIS_IN_HOUR) / MILLIS_IN_SECOND; | 91 filterStorage.addSubscription(subscription1); |
| 91 filterStorage.addSubscription(subscription2); | 92 |
| 92 | 93 let subscription2 = Subscription.fromURL("http://example.com/subscription2
"); |
| 93 let requests = []; | 94 subscription2.expires = |
| 94 let handler = metadata => | 95 subscription2.softExpiration = |
| 95 { | 96 (runner.currentTime + 2 * MILLIS_IN_HOUR) / MILLIS_IN_SECOND; |
| 96 requests.push([this.getTimeOffset(), metadata.method, metadata.path]); | 97 filterStorage.addSubscription(subscription2); |
| 97 return [200, "[Adblock]\n! ExPiREs: 1day\nfoo\nbar"]; | 98 |
| 98 }; | 99 let requests = []; |
| 99 | 100 let handler = metadata => |
| 100 this.registerHandler("/subscription1", handler); | 101 { |
| 101 this.registerHandler("/subscription2", handler); | 102 requests.push([runner.getTimeOffset(), metadata.method, metadata.path]); |
| 102 | 103 return [200, "[Adblock]\n! ExPiREs: 1day\nfoo\nbar"]; |
| 103 this.runScheduledTasks(55).then(() => | 104 }; |
| 104 { | 105 |
| 105 test.deepEqual(requests, [ | 106 runner.registerHandler("/subscription1", handler); |
| 106 [0 + initialDelay, "GET", "/subscription1"], | 107 runner.registerHandler("/subscription2", handler); |
| 107 [2 + initialDelay, "GET", "/subscription2"], | 108 |
| 108 [24 + initialDelay, "GET", "/subscription1"], | 109 return runner.runScheduledTasks(55).then(() => |
| 109 [26 + initialDelay, "GET", "/subscription2"], | 110 { |
| 110 [48 + initialDelay, "GET", "/subscription1"], | 111 assert.deepEqual(requests, [ |
| 111 [50 + initialDelay, "GET", "/subscription2"] | 112 [0 + initialDelay, "GET", "/subscription1"], |
| 112 ], "Requests after 55 hours"); | 113 [2 + initialDelay, "GET", "/subscription2"], |
| 113 }).catch(unexpectedError.bind(test)).then(() => test.done()); | 114 [24 + initialDelay, "GET", "/subscription1"], |
| 114 }; | 115 [26 + initialDelay, "GET", "/subscription2"], |
| 115 | 116 [48 + initialDelay, "GET", "/subscription1"], |
| 116 exports.testSubscriptionHeaders = {}; | 117 [50 + initialDelay, "GET", "/subscription2"] |
| 117 | 118 ], "Requests after 55 hours"); |
| 118 for (let currentTest of [ | 119 }); |
| 119 {header: "[Adblock]", downloadStatus: "synchronize_ok", requiredVersion: null}
, | 120 }); |
| 120 {header: "[Adblock Plus]", downloadStatus: "synchronize_ok", requiredVersion:
null}, | 121 }); |
| 121 {header: "(something)[Adblock]", downloadStatus: "synchronize_ok", requiredVer
sion: null}, | 122 |
| 122 {header: "[Adblock Plus 0.0.1]", downloadStatus: "synchronize_ok", requiredVer
sion: "0.0.1"}, | 123 describe("Subscription Headers", () => |
| 123 {header: "[Adblock Plus 99.9]", downloadStatus: "synchronize_ok", requiredVers
ion: "99.9"}, | 124 { |
| 124 {header: "[Foo]", downloadStatus: "synchronize_invalid_data", requiredVersion:
null} | 125 for (let currentTest of [ |
| 125 ]) | 126 {header: "[Adblock]", downloadStatus: "synchronize_ok", requiredVersion: n
ull}, |
| 126 { | 127 {header: "[Adblock Plus]", downloadStatus: "synchronize_ok", requiredVersi
on: null}, |
| 127 exports.testSubscriptionHeaders[currentTest.header] = function(test) | 128 {header: "(something)[Adblock]", downloadStatus: "synchronize_ok", require
dVersion: null}, |
| 128 { | 129 {header: "[Adblock Plus 0.0.1]", downloadStatus: "synchronize_ok", require
dVersion: "0.0.1"}, |
| 130 {header: "[Adblock Plus 99.9]", downloadStatus: "synchronize_ok", required
Version: "99.9"}, |
| 131 {header: "[Foo]", downloadStatus: "synchronize_invalid_data", requiredVers
ion: null} |
| 132 ]) |
| 133 { |
| 134 it(currentTest.header, () => |
| 135 { |
| 136 let subscription = Subscription.fromURL("http://example.com/subscription
"); |
| 137 filterStorage.addSubscription(subscription); |
| 138 |
| 139 runner.registerHandler("/subscription", metadata => |
| 140 { |
| 141 return [200, currentTest.header + "\n!Expires: 8 hours\nfoo\n!bar\n\n@
@bas\n#bam"]; |
| 142 }); |
| 143 |
| 144 return runner.runScheduledTasks(2).then(() => |
| 145 { |
| 146 assert.equal(subscription.downloadStatus, currentTest.downloadStatus,
"Download status"); |
| 147 assert.equal(subscription.requiredVersion, currentTest.requiredVersion
, "Required version"); |
| 148 |
| 149 if (currentTest.downloadStatus == "synchronize_ok") |
| 150 { |
| 151 assert.deepEqual([...subscription.filterText()], ["foo", "!bar", "@@
bas", "#bam"], "Resulting subscription filters"); |
| 152 } |
| 153 else |
| 154 { |
| 155 assert.deepEqual([...subscription.filterText()], [ |
| 156 ], "Resulting subscription filters"); |
| 157 } |
| 158 }); |
| 159 }); |
| 160 } |
| 161 }); |
| 162 |
| 163 it("Disable Updates", () => |
| 164 { |
| 165 Prefs.subscriptions_autoupdate = false; |
| 166 |
| 129 let subscription = Subscription.fromURL("http://example.com/subscription"); | 167 let subscription = Subscription.fromURL("http://example.com/subscription"); |
| 130 filterStorage.addSubscription(subscription); | 168 filterStorage.addSubscription(subscription); |
| 131 | 169 |
| 132 this.registerHandler("/subscription", metadata => | 170 let requests = 0; |
| 133 { | 171 runner.registerHandler("/subscription", metadata => |
| 134 return [200, currentTest.header + "\n!Expires: 8 hours\nfoo\n!bar\n\n@@bas
\n#bam"]; | 172 { |
| 135 }); | 173 requests++; |
| 136 | 174 throw new Error("Unexpected request"); |
| 137 this.runScheduledTasks(2).then(() => | 175 }); |
| 138 { | 176 |
| 139 test.equal(subscription.downloadStatus, currentTest.downloadStatus, "Downl
oad status"); | 177 return runner.runScheduledTasks(50).then(() => |
| 140 test.equal(subscription.requiredVersion, currentTest.requiredVersion, "Req
uired version"); | 178 { |
| 141 | 179 assert.equal(requests, 0, "Request count"); |
| 142 if (currentTest.downloadStatus == "synchronize_ok") | 180 }); |
| 143 { | 181 }); |
| 144 test.deepEqual([...subscription.filterText()], ["foo", "!bar", "@@bas",
"#bam"], "Resulting subscription filters"); | 182 |
| 183 describe("Expiration time", () => |
| 184 { |
| 185 for (let currentTest of [ |
| 186 { |
| 187 expiration: "default", |
| 188 randomResult: 0.5, |
| 189 requests: [0 + initialDelay, 5 * 24 + initialDelay] |
| 190 }, |
| 191 { |
| 192 expiration: "1 hours", // Minimal expiration interval |
| 193 randomResult: 0.5, |
| 194 requests: [0 + initialDelay, 1 + initialDelay, 2 + initialDelay, 3 + ini
tialDelay] |
| 195 }, |
| 196 { |
| 197 expiration: "26 hours", |
| 198 randomResult: 0.5, |
| 199 requests: [0 + initialDelay, 26 + initialDelay] |
| 200 }, |
| 201 { |
| 202 expiration: "2 days", |
| 203 randomResult: 0.5, |
| 204 requests: [0 + initialDelay, 48 + initialDelay] |
| 205 }, |
| 206 { |
| 207 expiration: "20 days", // Too large, will be corrected |
| 208 randomResult: 0.5, |
| 209 requests: [0 + initialDelay, 14 * 24 + initialDelay] |
| 210 }, |
| 211 { |
| 212 expiration: "35 hours", |
| 213 randomResult: 0, // Changes interval by factor 0.8 |
| 214 requests: [0 + initialDelay, 28 + initialDelay] |
| 215 }, |
| 216 { |
| 217 expiration: "35 hours", |
| 218 randomResult: 1, // Changes interval by factor 1.2 |
| 219 requests: [0 + initialDelay, 42 + initialDelay] |
| 220 }, |
| 221 { |
| 222 expiration: "35 hours", |
| 223 randomResult: 0.25, // Changes interval by factor 0.9 |
| 224 requests: [0 + initialDelay, 32 + initialDelay] |
| 225 }, |
| 226 { |
| 227 expiration: "40 hours", |
| 228 randomResult: 0.5, |
| 229 skipAfter: 5 + initialDelay, |
| 230 skip: 10, // Short break should not increase soft expirati
on |
| 231 requests: [0 + initialDelay, 40 + initialDelay] |
| 232 }, |
| 233 { |
| 234 expiration: "40 hours", |
| 235 randomResult: 0.5, |
| 236 skipAfter: 5 + initialDelay, |
| 237 skip: 30, // Long break should increase soft expiration |
| 238 requests: [0 + initialDelay, 70 + initialDelay] |
| 239 }, |
| 240 { |
| 241 expiration: "40 hours", |
| 242 randomResult: 0.5, |
| 243 skipAfter: 5 + initialDelay, |
| 244 skip: 80, // Hitting hard expiration, immediate download |
| 245 requests: [0 + initialDelay, 85 + initialDelay] |
| 145 } | 246 } |
| 146 else | 247 ]) |
| 147 { | 248 { |
| 148 test.deepEqual([...subscription.filterText()], [ | 249 let testId = `"${currentTest.expiration}"`; |
| 149 ], "Resulting subscription filters"); | 250 if (currentTest.randomResult != 0.5) |
| 150 } | 251 testId += ` with Math.random() returning ${currentTest.randomResult}`; |
| 151 }).catch(unexpectedError.bind(test)).then(() => test.done()); | 252 if (currentTest.skip) |
| 152 }; | 253 testId += ` skipping ${currentTest.skip} hours after ${currentTest.skipA
fter} hours`; |
| 153 } | 254 |
| 154 | 255 it(testId, () => |
| 155 exports.testsDisabledUpdates = function(test) | 256 { |
| 156 { | 257 let subscription = Subscription.fromURL("http://example.com/subscription
"); |
| 157 Prefs.subscriptions_autoupdate = false; | 258 filterStorage.addSubscription(subscription); |
| 158 | 259 |
| 159 let subscription = Subscription.fromURL("http://example.com/subscription"); | 260 let requests = []; |
| 160 filterStorage.addSubscription(subscription); | 261 runner.registerHandler("/subscription", metadata => |
| 161 | 262 { |
| 162 let requests = 0; | 263 requests.push(runner.getTimeOffset()); |
| 163 this.registerHandler("/subscription", metadata => | 264 return [200, "[Adblock]\n!Expires: " + currentTest.expiration + "\nbar
"]; |
| 164 { | 265 }); |
| 165 requests++; | 266 |
| 166 throw new Error("Unexpected request"); | 267 runner.randomResult = currentTest.randomResult; |
| 167 }); | 268 |
| 168 | 269 let maxHours = Math.round(Math.max.apply(null, currentTest.requests)) +
1; |
| 169 this.runScheduledTasks(50).then(() => | 270 return runner.runScheduledTasks(maxHours, currentTest.skipAfter, current
Test.skip).then(() => |
| 170 { | 271 { |
| 171 test.equal(requests, 0, "Request count"); | 272 assert.deepEqual(requests, currentTest.requests, "Requests"); |
| 172 }).catch(unexpectedError.bind(test)).then(() => test.done()); | 273 }); |
| 173 }; | 274 }); |
| 174 | 275 } |
| 175 exports.testExpirationTime = {}; | 276 }); |
| 176 | 277 |
| 177 for (let currentTest of [ | 278 describe("Special Comments", () => |
| 178 { | 279 { |
| 179 expiration: "default", | 280 for (let [comment, check] of [ |
| 180 randomResult: 0.5, | 281 ["! Homepage: http://example.com/", subscription => |
| 181 requests: [0 + initialDelay, 5 * 24 + initialDelay] | 282 { |
| 182 }, | 283 assert.equal(subscription.homepage, "http://example.com/", "Valid homepa
ge comment"); |
| 183 { | 284 }], |
| 184 expiration: "1 hours", // Minimal expiration interval | 285 ["! Homepage: ssh://example.com/", subscription => |
| 185 randomResult: 0.5, | 286 { |
| 186 requests: [0 + initialDelay, 1 + initialDelay, 2 + initialDelay, 3 + initial
Delay] | 287 assert.equal(subscription.homepage, null, "Invalid homepage comment"); |
| 187 }, | 288 }], |
| 188 { | 289 ["! Title: foo", subscription => |
| 189 expiration: "26 hours", | 290 { |
| 190 randomResult: 0.5, | 291 assert.equal(subscription.title, "foo", "Title comment"); |
| 191 requests: [0 + initialDelay, 26 + initialDelay] | 292 assert.equal(subscription.fixedTitle, true, "Fixed title"); |
| 192 }, | 293 }], |
| 193 { | 294 ["! Version: 1234", subscription => |
| 194 expiration: "2 days", | 295 { |
| 195 randomResult: 0.5, | 296 assert.equal(subscription.version, 1234, "Version comment"); |
| 196 requests: [0 + initialDelay, 48 + initialDelay] | 297 }] |
| 197 }, | 298 ]) |
| 198 { | 299 { |
| 199 expiration: "20 days", // Too large, will be corrected | 300 it(comment, () => |
| 200 randomResult: 0.5, | 301 { |
| 201 requests: [0 + initialDelay, 14 * 24 + initialDelay] | 302 let subscription = Subscription.fromURL("http://example.com/subscription
"); |
| 202 }, | 303 filterStorage.addSubscription(subscription); |
| 203 { | 304 |
| 204 expiration: "35 hours", | 305 runner.registerHandler("/subscription", metadata => |
| 205 randomResult: 0, // Changes interval by factor 0.8 | 306 { |
| 206 requests: [0 + initialDelay, 28 + initialDelay] | 307 return [200, "[Adblock]\n" + comment + "\nfoo\nbar"]; |
| 207 }, | 308 }); |
| 208 { | 309 |
| 209 expiration: "35 hours", | 310 return runner.runScheduledTasks(2).then(() => |
| 210 randomResult: 1, // Changes interval by factor 1.2 | 311 { |
| 211 requests: [0 + initialDelay, 42 + initialDelay] | 312 check(subscription); |
| 212 }, | 313 assert.deepEqual([...subscription.filterText()], ["foo", "bar"], "Spec
ial comment not added to filters"); |
| 213 { | 314 }); |
| 214 expiration: "35 hours", | 315 }); |
| 215 randomResult: 0.25, // Changes interval by factor 0.9 | 316 } |
| 216 requests: [0 + initialDelay, 32 + initialDelay] | 317 }); |
| 217 }, | 318 |
| 218 { | 319 it("Redirects", () => |
| 219 expiration: "40 hours", | |
| 220 randomResult: 0.5, | |
| 221 skipAfter: 5 + initialDelay, | |
| 222 skip: 10, // Short break should not increase soft expiration | |
| 223 requests: [0 + initialDelay, 40 + initialDelay] | |
| 224 }, | |
| 225 { | |
| 226 expiration: "40 hours", | |
| 227 randomResult: 0.5, | |
| 228 skipAfter: 5 + initialDelay, | |
| 229 skip: 30, // Long break should increase soft expiration | |
| 230 requests: [0 + initialDelay, 70 + initialDelay] | |
| 231 }, | |
| 232 { | |
| 233 expiration: "40 hours", | |
| 234 randomResult: 0.5, | |
| 235 skipAfter: 5 + initialDelay, | |
| 236 skip: 80, // Hitting hard expiration, immediate download | |
| 237 requests: [0 + initialDelay, 85 + initialDelay] | |
| 238 } | |
| 239 ]) | |
| 240 { | |
| 241 let testId = `"${currentTest.expiration}"`; | |
| 242 if (currentTest.randomResult != 0.5) | |
| 243 testId += " with Math.random() returning " + currentTest.randomResult; | |
| 244 if (currentTest.skip) | |
| 245 testId += " skipping " + currentTest.skip + " hours after " + currentTest.sk
ipAfter + " hours"; | |
| 246 exports.testExpirationTime[testId] = function(test) | |
| 247 { | 320 { |
| 248 let subscription = Subscription.fromURL("http://example.com/subscription"); | 321 let subscription = Subscription.fromURL("http://example.com/subscription"); |
| 249 filterStorage.addSubscription(subscription); | 322 filterStorage.addSubscription(subscription); |
| 250 | 323 |
| 251 let requests = []; | 324 runner.registerHandler("/subscription", metadata => |
| 252 this.registerHandler("/subscription", metadata => | 325 { |
| 253 { | 326 return [200, "[Adblock]\n!Redirect: http://example.com/redirected\nbar"]; |
| 254 requests.push(this.getTimeOffset()); | 327 }); |
| 255 return [200, "[Adblock]\n!Expires: " + currentTest.expiration + "\nbar"]; | 328 |
| 256 }); | 329 let requests; |
| 257 | 330 |
| 258 this.randomResult = currentTest.randomResult; | 331 return runner.runScheduledTasks(30).then(() => |
| 259 | 332 { |
| 260 let maxHours = Math.round(Math.max.apply(null, currentTest.requests)) + 1; | 333 assert.equal([...filterStorage.subscriptions()][0], subscription, "Invalid
redirect ignored"); |
| 261 this.runScheduledTasks(maxHours, currentTest.skipAfter, currentTest.skip).th
en(() => | 334 assert.equal(subscription.downloadStatus, "synchronize_connection_error",
"Connection error recorded"); |
| 262 { | 335 assert.equal(subscription.errors, 2, "Number of download errors"); |
| 263 test.deepEqual(requests, currentTest.requests, "Requests"); | 336 |
| 264 }).catch(unexpectedError.bind(test)).then(() => test.done()); | 337 requests = []; |
| 265 }; | 338 |
| 266 } | 339 runner.registerHandler("/redirected", metadata => |
| 267 | 340 { |
| 268 exports.testSpecialComments = {}; | 341 requests.push(runner.getTimeOffset()); |
| 269 | 342 return [200, "[Adblock]\n! Expires: 8 hours\nbar"]; |
| 270 for (let [comment, check] of [ | 343 }); |
| 271 ["! Homepage: http://example.com/", (test, subscription) => | 344 |
| 272 { | 345 resetSubscription(subscription); |
| 273 test.equal(subscription.homepage, "http://example.com/", "Valid homepage com
ment"); | 346 return runner.runScheduledTasks(15); |
| 274 }], | 347 }).then(() => |
| 275 ["! Homepage: ssh://example.com/", (test, subscription) => | 348 { |
| 276 { | 349 assert.equal([...filterStorage.subscriptions()][0].url, "http://example.co
m/redirected", "Redirect followed"); |
| 277 test.equal(subscription.homepage, null, "Invalid homepage comment"); | 350 assert.deepEqual(requests, [0 + initialDelay, 8 + initialDelay], "Resultin
g requests"); |
| 278 }], | 351 |
| 279 ["! Title: foo", (test, subscription) => | 352 runner.registerHandler("/redirected", metadata => |
| 280 { | 353 { |
| 281 test.equal(subscription.title, "foo", "Title comment"); | 354 return [200, "[Adblock]\n!Redirect: http://example.com/subscription\nbar
"]; |
| 282 test.equal(subscription.fixedTitle, true, "Fixed title"); | 355 }); |
| 283 }], | 356 |
| 284 ["! Version: 1234", (test, subscription) => | 357 subscription = Subscription.fromURL("http://example.com/subscription"); |
| 285 { | 358 resetSubscription(subscription); |
| 286 test.equal(subscription.version, 1234, "Version comment"); | 359 filterStorage.removeSubscription([...filterStorage.subscriptions()][0]); |
| 287 }] | 360 filterStorage.addSubscription(subscription); |
| 288 ]) | 361 |
| 289 { | 362 return runner.runScheduledTasks(2); |
| 290 exports.testSpecialComments[comment] = function(test) | 363 }).then(() => |
| 291 { | 364 { |
| 365 assert.equal([...filterStorage.subscriptions()][0], subscription, "Redirec
t not followed on redirect loop"); |
| 366 assert.equal(subscription.downloadStatus, "synchronize_connection_error",
"Download status after redirect loop"); |
| 367 }); |
| 368 }); |
| 369 |
| 370 it("Fallback", () => |
| 371 { |
| 372 Prefs.subscriptions_fallbackerrors = 3; |
| 373 Prefs.subscriptions_fallbackurl = "http://example.com/fallback?%SUBSCRIPTION
%&%RESPONSESTATUS%"; |
| 374 |
| 292 let subscription = Subscription.fromURL("http://example.com/subscription"); | 375 let subscription = Subscription.fromURL("http://example.com/subscription"); |
| 293 filterStorage.addSubscription(subscription); | 376 filterStorage.addSubscription(subscription); |
| 294 | 377 |
| 295 this.registerHandler("/subscription", metadata => | 378 // No valid response from fallback |
| 296 { | 379 |
| 297 return [200, "[Adblock]\n" + comment + "\nfoo\nbar"]; | 380 let requests = []; |
| 298 }); | 381 let fallbackParams; |
| 299 | 382 let redirectedRequests; |
| 300 this.runScheduledTasks(2).then(() => | 383 runner.registerHandler("/subscription", metadata => |
| 301 { | 384 { |
| 302 check(test, subscription); | 385 requests.push(runner.getTimeOffset()); |
| 303 test.deepEqual([...subscription.filterText()], ["foo", "bar"], "Special co
mment not added to filters"); | 386 return [404, ""]; |
| 304 }).catch(unexpectedError.bind(test)).then(() => test.done()); | 387 }); |
| 305 }; | 388 |
| 306 } | 389 return runner.runScheduledTasks(100).then(() => |
| 307 | 390 { |
| 308 exports.testRedirects = function(test) | 391 assert.deepEqual(requests, [0 + initialDelay, 24 + initialDelay, 48 + init
ialDelay, 72 + initialDelay, 96 + initialDelay], "Continue trying if the fallbac
k doesn't respond"); |
| 309 { | 392 |
| 310 let subscription = Subscription.fromURL("http://example.com/subscription"); | 393 // Fallback giving "Gone" response |
| 311 filterStorage.addSubscription(subscription); | 394 |
| 312 | 395 resetSubscription(subscription); |
| 313 this.registerHandler("/subscription", metadata => | 396 requests = []; |
| 314 { | 397 fallbackParams = null; |
| 315 return [200, "[Adblock]\n!Redirect: http://example.com/redirected\nbar"]; | 398 runner.registerHandler("/fallback", metadata => |
| 316 }); | 399 { |
| 317 | 400 fallbackParams = decodeURIComponent(metadata.queryString); |
| 318 let requests; | 401 return [200, "410 Gone"]; |
| 319 | 402 }); |
| 320 this.runScheduledTasks(30).then(() => | 403 |
| 321 { | 404 return runner.runScheduledTasks(100); |
| 322 test.equal([...filterStorage.subscriptions()][0], subscription, "Invalid red
irect ignored"); | 405 }).then(() => |
| 323 test.equal(subscription.downloadStatus, "synchronize_connection_error", "Con
nection error recorded"); | 406 { |
| 324 test.equal(subscription.errors, 2, "Number of download errors"); | 407 assert.deepEqual(requests, [0 + initialDelay, 24 + initialDelay, 48 + init
ialDelay], "Stop trying if the fallback responds with Gone"); |
| 325 | 408 assert.equal(fallbackParams, "http://example.com/subscription&404", "Fallb
ack arguments"); |
| 326 requests = []; | 409 |
| 327 | 410 // Fallback redirecting to a missing file |
| 328 this.registerHandler("/redirected", metadata => | 411 |
| 329 { | 412 subscription = Subscription.fromURL("http://example.com/subscription"); |
| 330 requests.push(this.getTimeOffset()); | 413 resetSubscription(subscription); |
| 331 return [200, "[Adblock]\n! Expires: 8 hours\nbar"]; | 414 filterStorage.removeSubscription([...filterStorage.subscriptions()][0]); |
| 332 }); | 415 filterStorage.addSubscription(subscription); |
| 333 | 416 requests = []; |
| 334 resetSubscription(subscription); | 417 |
| 335 return this.runScheduledTasks(15); | 418 runner.registerHandler("/fallback", metadata => |
| 336 }).then(() => | 419 { |
| 337 { | 420 return [200, "301 http://example.com/redirected"]; |
| 338 test.equal([...filterStorage.subscriptions()][0].url, "http://example.com/re
directed", "Redirect followed"); | 421 }); |
| 339 test.deepEqual(requests, [0 + initialDelay, 8 + initialDelay], "Resulting re
quests"); | 422 return runner.runScheduledTasks(100); |
| 340 | 423 }).then(() => |
| 341 this.registerHandler("/redirected", metadata => | 424 { |
| 342 { | 425 assert.equal([...filterStorage.subscriptions()][0].url, "http://example.co
m/subscription", "Ignore invalid redirect from fallback"); |
| 343 return [200, "[Adblock]\n!Redirect: http://example.com/subscription\nbar"]
; | 426 assert.deepEqual(requests, [0 + initialDelay, 24 + initialDelay, 48 + init
ialDelay, 72 + initialDelay, 96 + initialDelay], "Requests not affected by inval
id redirect"); |
| 344 }); | 427 |
| 345 | 428 // Fallback redirecting to an existing file |
| 346 subscription = Subscription.fromURL("http://example.com/subscription"); | 429 |
| 347 resetSubscription(subscription); | 430 resetSubscription(subscription); |
| 348 filterStorage.removeSubscription([...filterStorage.subscriptions()][0]); | 431 requests = []; |
| 432 redirectedRequests = []; |
| 433 runner.registerHandler("/redirected", metadata => |
| 434 { |
| 435 redirectedRequests.push(runner.getTimeOffset()); |
| 436 return [200, "[Adblock]\n!Expires: 1day\nfoo\nbar"]; |
| 437 }); |
| 438 |
| 439 return runner.runScheduledTasks(100); |
| 440 }).then(() => |
| 441 { |
| 442 assert.equal([...filterStorage.subscriptions()][0].url, "http://example.co
m/redirected", "Valid redirect from fallback is followed"); |
| 443 assert.deepEqual(requests, [0 + initialDelay, 24 + initialDelay, 48 + init
ialDelay], "Stop polling original URL after a valid redirect from fallback"); |
| 444 assert.deepEqual(redirectedRequests, [48 + initialDelay, 72 + initialDelay
, 96 + initialDelay], "Request new URL after a valid redirect from fallback"); |
| 445 |
| 446 // Redirect loop |
| 447 |
| 448 runner.registerHandler("/subscription", metadata => |
| 449 { |
| 450 return [200, "[Adblock]\n! Redirect: http://example.com/subscription2"]; |
| 451 }); |
| 452 runner.registerHandler("/subscription2", metadata => |
| 453 { |
| 454 return [200, "[Adblock]\n! Redirect: http://example.com/subscription"]; |
| 455 }); |
| 456 |
| 457 subscription = Subscription.fromURL("http://example.com/subscription"); |
| 458 resetSubscription(subscription); |
| 459 filterStorage.removeSubscription([...filterStorage.subscriptions()][0]); |
| 460 filterStorage.addSubscription(subscription); |
| 461 |
| 462 return runner.runScheduledTasks(100); |
| 463 }).then(() => |
| 464 { |
| 465 assert.equal([...filterStorage.subscriptions()][0].url, "http://example.co
m/redirected", "Fallback can still redirect even after a redirect loop"); |
| 466 }); |
| 467 }); |
| 468 |
| 469 it("State Fields", () => |
| 470 { |
| 471 let subscription = Subscription.fromURL("http://example.com/subscription"); |
| 349 filterStorage.addSubscription(subscription); | 472 filterStorage.addSubscription(subscription); |
| 350 | 473 |
| 351 return this.runScheduledTasks(2); | 474 runner.registerHandler("/subscription", metadata => |
| 352 }).then(() => | 475 { |
| 353 { | 476 return [200, "[Adblock]\n! Expires: 2 hours\nfoo\nbar"]; |
| 354 test.equal([...filterStorage.subscriptions()][0], subscription, "Redirect no
t followed on redirect loop"); | 477 }); |
| 355 test.equal(subscription.downloadStatus, "synchronize_connection_error", "Dow
nload status after redirect loop"); | 478 |
| 356 }).catch(unexpectedError.bind(test)).then(() => test.done()); | 479 let startTime = runner.currentTime; |
| 357 }; | 480 return runner.runScheduledTasks(2).then(() => |
| 358 | 481 { |
| 359 exports.testFallback = function(test) | 482 assert.equal(subscription.downloadStatus, "synchronize_ok", "downloadStatu
s after successful download"); |
| 360 { | 483 assert.equal(subscription.lastDownload * MILLIS_IN_SECOND, startTime + ini
tialDelay * MILLIS_IN_HOUR, "lastDownload after successful download"); |
| 361 Prefs.subscriptions_fallbackerrors = 3; | 484 assert.equal(subscription.lastSuccess * MILLIS_IN_SECOND, startTime + init
ialDelay * MILLIS_IN_HOUR, "lastSuccess after successful download"); |
| 362 Prefs.subscriptions_fallbackurl = "http://example.com/fallback?%SUBSCRIPTION%&
%RESPONSESTATUS%"; | 485 assert.equal(subscription.lastCheck * MILLIS_IN_SECOND, startTime + (1 + i
nitialDelay) * MILLIS_IN_HOUR, "lastCheck after successful download"); |
| 363 | 486 assert.equal(subscription.errors, 0, "errors after successful download"); |
| 364 let subscription = Subscription.fromURL("http://example.com/subscription"); | 487 |
| 365 filterStorage.addSubscription(subscription); | 488 runner.registerHandler("/subscription", metadata => |
| 366 | 489 { |
| 367 // No valid response from fallback | 490 return [0, ""]; |
| 368 | 491 }); |
| 369 let requests = []; | 492 |
| 370 let fallbackParams; | 493 return runner.runScheduledTasks(2); |
| 371 let redirectedRequests; | 494 }).then(() => |
| 372 this.registerHandler("/subscription", metadata => | 495 { |
| 373 { | 496 assert.equal(subscription.downloadStatus, "synchronize_connection_error",
"downloadStatus after connection error"); |
| 374 requests.push(this.getTimeOffset()); | 497 assert.equal(subscription.lastDownload * MILLIS_IN_SECOND, startTime + (2
+ initialDelay) * MILLIS_IN_HOUR, "lastDownload after connection error"); |
| 375 return [404, ""]; | 498 assert.equal(subscription.lastSuccess * MILLIS_IN_SECOND, startTime + init
ialDelay * MILLIS_IN_HOUR, "lastSuccess after connection error"); |
| 376 }); | 499 assert.equal(subscription.lastCheck * MILLIS_IN_SECOND, startTime + (3 + i
nitialDelay) * MILLIS_IN_HOUR, "lastCheck after connection error"); |
| 377 | 500 assert.equal(subscription.errors, 1, "errors after connection error"); |
| 378 this.runScheduledTasks(100).then(() => | 501 |
| 379 { | 502 runner.registerHandler("/subscription", metadata => |
| 380 test.deepEqual(requests, [0 + initialDelay, 24 + initialDelay, 48 + initialD
elay, 72 + initialDelay, 96 + initialDelay], "Continue trying if the fallback do
esn't respond"); | 503 { |
| 381 | 504 return [404, ""]; |
| 382 // Fallback giving "Gone" response | 505 }); |
| 383 | 506 |
| 384 resetSubscription(subscription); | 507 return runner.runScheduledTasks(24); |
| 385 requests = []; | 508 }).then(() => |
| 386 fallbackParams = null; | 509 { |
| 387 this.registerHandler("/fallback", metadata => | 510 assert.equal(subscription.downloadStatus, "synchronize_connection_error",
"downloadStatus after download error"); |
| 388 { | 511 assert.equal(subscription.lastDownload * MILLIS_IN_SECOND, startTime + (26
+ initialDelay) * MILLIS_IN_HOUR, "lastDownload after download error"); |
| 389 fallbackParams = decodeURIComponent(metadata.queryString); | 512 assert.equal(subscription.lastSuccess * MILLIS_IN_SECOND, startTime + init
ialDelay * MILLIS_IN_HOUR, "lastSuccess after download error"); |
| 390 return [200, "410 Gone"]; | 513 assert.equal(subscription.lastCheck * MILLIS_IN_SECOND, startTime + (27 +
initialDelay) * MILLIS_IN_HOUR, "lastCheck after download error"); |
| 391 }); | 514 assert.equal(subscription.errors, 2, "errors after download error"); |
| 392 | 515 }); |
| 393 return this.runScheduledTasks(100); | 516 }); |
| 394 }).then(() => | 517 |
| 395 { | 518 it("Special Comment Ordering", () => |
| 396 test.deepEqual(requests, [0 + initialDelay, 24 + initialDelay, 48 + initialD
elay], "Stop trying if the fallback responds with Gone"); | 519 { |
| 397 test.equal(fallbackParams, "http://example.com/subscription&404", "Fallback
arguments"); | 520 let subscription = Subscription.fromURL("http://example.com/subscription"); |
| 398 | |
| 399 // Fallback redirecting to a missing file | |
| 400 | |
| 401 subscription = Subscription.fromURL("http://example.com/subscription"); | |
| 402 resetSubscription(subscription); | |
| 403 filterStorage.removeSubscription([...filterStorage.subscriptions()][0]); | |
| 404 filterStorage.addSubscription(subscription); | 521 filterStorage.addSubscription(subscription); |
| 405 requests = []; | 522 |
| 406 | 523 runner.registerHandler("/subscription", metadata => |
| 407 this.registerHandler("/fallback", metadata => | 524 { |
| 408 { | 525 return [0, ""]; |
| 409 return [200, "301 http://example.com/redirected"]; | 526 }); |
| 410 }); | 527 |
| 411 return this.runScheduledTasks(100); | 528 return runner.runScheduledTasks(1).then(() => |
| 412 }).then(() => | 529 { |
| 413 { | 530 assert.equal(subscription.title, "http://example.com/subscription", "make
sure title was not found"); |
| 414 test.equal([...filterStorage.subscriptions()][0].url, "http://example.com/su
bscription", "Ignore invalid redirect from fallback"); | 531 }); |
| 415 test.deepEqual(requests, [0 + initialDelay, 24 + initialDelay, 48 + initialD
elay, 72 + initialDelay, 96 + initialDelay], "Requests not affected by invalid r
edirect"); | 532 }); |
| 416 | 533 |
| 417 // Fallback redirecting to an existing file | 534 it("Unkown Special Comments", () => |
| 418 | 535 { |
| 419 resetSubscription(subscription); | 536 let subscription = Subscription.fromURL("http://example.com/subscription"); |
| 420 requests = []; | |
| 421 redirectedRequests = []; | |
| 422 this.registerHandler("/redirected", metadata => | |
| 423 { | |
| 424 redirectedRequests.push(this.getTimeOffset()); | |
| 425 return [200, "[Adblock]\n!Expires: 1day\nfoo\nbar"]; | |
| 426 }); | |
| 427 | |
| 428 return this.runScheduledTasks(100); | |
| 429 }).then(() => | |
| 430 { | |
| 431 test.equal([...filterStorage.subscriptions()][0].url, "http://example.com/re
directed", "Valid redirect from fallback is followed"); | |
| 432 test.deepEqual(requests, [0 + initialDelay, 24 + initialDelay, 48 + initialD
elay], "Stop polling original URL after a valid redirect from fallback"); | |
| 433 test.deepEqual(redirectedRequests, [48 + initialDelay, 72 + initialDelay, 96
+ initialDelay], "Request new URL after a valid redirect from fallback"); | |
| 434 | |
| 435 // Redirect loop | |
| 436 | |
| 437 this.registerHandler("/subscription", metadata => | |
| 438 { | |
| 439 return [200, "[Adblock]\n! Redirect: http://example.com/subscription2"]; | |
| 440 }); | |
| 441 this.registerHandler("/subscription2", metadata => | |
| 442 { | |
| 443 return [200, "[Adblock]\n! Redirect: http://example.com/subscription"]; | |
| 444 }); | |
| 445 | |
| 446 subscription = Subscription.fromURL("http://example.com/subscription"); | |
| 447 resetSubscription(subscription); | |
| 448 filterStorage.removeSubscription([...filterStorage.subscriptions()][0]); | |
| 449 filterStorage.addSubscription(subscription); | 537 filterStorage.addSubscription(subscription); |
| 450 | 538 |
| 451 return this.runScheduledTasks(100); | 539 runner.registerHandler("/subscription", metadata => |
| 452 }).then(() => | 540 { |
| 453 { | 541 // To test allowing unknown special comments like `! :`, `!!@#$%^&*() : `,
and `! Some Unknown Comment : ` |
| 454 test.equal([...filterStorage.subscriptions()][0].url, "http://example.com/re
directed", "Fallback can still redirect even after a redirect loop"); | 542 return [200, "[Adblock]\n! :\n! !@#$%^&*() :\n! Some Unknown Comment :\n!
Title: foobar\nfoo\nbar"]; |
| 455 }).catch(unexpectedError.bind(test)).then(() => test.done()); | 543 }); |
| 456 }; | 544 |
| 457 | 545 return runner.runScheduledTasks(1).then(() => |
| 458 exports.testStateFields = function(test) | 546 { |
| 459 { | 547 assert.equal(subscription.title, "foobar", "make sure title was found"); |
| 460 let subscription = Subscription.fromURL("http://example.com/subscription"); | 548 }); |
| 461 filterStorage.addSubscription(subscription); | 549 }); |
| 462 | 550 }); |
| 463 this.registerHandler("/subscription", metadata => | |
| 464 { | |
| 465 return [200, "[Adblock]\n! Expires: 2 hours\nfoo\nbar"]; | |
| 466 }); | |
| 467 | |
| 468 let startTime = this.currentTime; | |
| 469 this.runScheduledTasks(2).then(() => | |
| 470 { | |
| 471 test.equal(subscription.downloadStatus, "synchronize_ok", "downloadStatus af
ter successful download"); | |
| 472 test.equal(subscription.lastDownload * MILLIS_IN_SECOND, startTime + initial
Delay * MILLIS_IN_HOUR, "lastDownload after successful download"); | |
| 473 test.equal(subscription.lastSuccess * MILLIS_IN_SECOND, startTime + initialD
elay * MILLIS_IN_HOUR, "lastSuccess after successful download"); | |
| 474 test.equal(subscription.lastCheck * MILLIS_IN_SECOND, startTime + (1 + initi
alDelay) * MILLIS_IN_HOUR, "lastCheck after successful download"); | |
| 475 test.equal(subscription.errors, 0, "errors after successful download"); | |
| 476 | |
| 477 this.registerHandler("/subscription", metadata => | |
| 478 { | |
| 479 return [0, ""]; | |
| 480 }); | |
| 481 | |
| 482 return this.runScheduledTasks(2); | |
| 483 }).then(() => | |
| 484 { | |
| 485 test.equal(subscription.downloadStatus, "synchronize_connection_error", "dow
nloadStatus after connection error"); | |
| 486 test.equal(subscription.lastDownload * MILLIS_IN_SECOND, startTime + (2 + in
itialDelay) * MILLIS_IN_HOUR, "lastDownload after connection error"); | |
| 487 test.equal(subscription.lastSuccess * MILLIS_IN_SECOND, startTime + initialD
elay * MILLIS_IN_HOUR, "lastSuccess after connection error"); | |
| 488 test.equal(subscription.lastCheck * MILLIS_IN_SECOND, startTime + (3 + initi
alDelay) * MILLIS_IN_HOUR, "lastCheck after connection error"); | |
| 489 test.equal(subscription.errors, 1, "errors after connection error"); | |
| 490 | |
| 491 this.registerHandler("/subscription", metadata => | |
| 492 { | |
| 493 return [404, ""]; | |
| 494 }); | |
| 495 | |
| 496 return this.runScheduledTasks(24); | |
| 497 }).then(() => | |
| 498 { | |
| 499 test.equal(subscription.downloadStatus, "synchronize_connection_error", "dow
nloadStatus after download error"); | |
| 500 test.equal(subscription.lastDownload * MILLIS_IN_SECOND, startTime + (26 + i
nitialDelay) * MILLIS_IN_HOUR, "lastDownload after download error"); | |
| 501 test.equal(subscription.lastSuccess * MILLIS_IN_SECOND, startTime + initialD
elay * MILLIS_IN_HOUR, "lastSuccess after download error"); | |
| 502 test.equal(subscription.lastCheck * MILLIS_IN_SECOND, startTime + (27 + init
ialDelay) * MILLIS_IN_HOUR, "lastCheck after download error"); | |
| 503 test.equal(subscription.errors, 2, "errors after download error"); | |
| 504 }).catch(unexpectedError.bind(test)).then(() => test.done()); | |
| 505 }; | |
| 506 | |
| 507 exports.testSpecialCommentOrdering = function(test) | |
| 508 { | |
| 509 let subscription = Subscription.fromURL("http://example.com/subscription"); | |
| 510 filterStorage.addSubscription(subscription); | |
| 511 | |
| 512 this.registerHandler("/subscription", metadata => | |
| 513 { | |
| 514 return [200, "[Adblock]\n! Special Comment: x\n!foo\n! Title: foobar\nfoo\nb
ar"]; | |
| 515 }); | |
| 516 | |
| 517 this.runScheduledTasks(1).then(() => | |
| 518 { | |
| 519 test.equal(subscription.title, "http://example.com/subscription", "make sure
title was not found"); | |
| 520 }).catch(unexpectedError.bind(test)).then(() => test.done()); | |
| 521 }; | |
| 522 | |
| 523 exports.testUnknownSpecialComments = function(test) | |
| 524 { | |
| 525 let subscription = Subscription.fromURL("http://example.com/subscription"); | |
| 526 filterStorage.addSubscription(subscription); | |
| 527 | |
| 528 this.registerHandler("/subscription", metadata => | |
| 529 { | |
| 530 // To test allowing unknown special comments like `! :`, `!!@#$%^&*() : `, a
nd `! Some Unknown Comment : ` | |
| 531 return [200, "[Adblock]\n! :\n! !@#$%^&*() :\n! Some Unknown Comment :\n! Ti
tle: foobar\nfoo\nbar"]; | |
| 532 }); | |
| 533 | |
| 534 this.runScheduledTasks(1).then(() => | |
| 535 { | |
| 536 test.equal(subscription.title, "foobar", "make sure title was found"); | |
| 537 }).catch(unexpectedError.bind(test)).then(() => test.done()); | |
| 538 }; | |
| OLD | NEW |