| 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 let {createSandbox} = require("./_common"); | 20 let {createSandbox} = require("./_common"); | 
|  | 21 const {withNAD, testEqualObjProperties} = require("./_test-utils"); | 
| 21 | 22 | 
| 22 let Filter = null; | 23 let Filter = null; | 
| 23 let Subscription = null; | 24 let Subscription = null; | 
| 24 let SpecialSubscription = null; | 25 let SpecialSubscription = null; | 
| 25 let DownloadableSubscription = null; | 26 let DownloadableSubscription = null; | 
| 26 let FilterNotifier = null; | 27 let FilterNotifier = null; | 
|  | 28 let Parser = null; | 
|  | 29 let Serializer = null; | 
| 27 | 30 | 
| 28 exports.setUp = function(callback) | 31 exports.setUp = function(callback) | 
| 29 { | 32 { | 
| 30   let sandboxedRequire = createSandbox(); | 33   let sandboxedRequire = createSandbox(); | 
| 31   ({Filter} = sandboxedRequire("../lib/filterClasses")); | 34   ({Filter} = sandboxedRequire("../lib/filterClasses")); | 
| 32   ( | 35   ( | 
| 33     { | 36     { | 
| 34       Subscription, SpecialSubscription, DownloadableSubscription | 37       Subscription, SpecialSubscription, DownloadableSubscription | 
| 35     } = sandboxedRequire("../lib/subscriptionClasses") | 38     } = sandboxedRequire("../lib/subscriptionClasses") | 
| 36   ); | 39   ); | 
| 37   ({FilterNotifier} = sandboxedRequire("../lib/filterNotifier")); | 40   ({FilterNotifier} = sandboxedRequire("../lib/filterNotifier")); | 
|  | 41   ({Parser, Serializer} = sandboxedRequire("../lib/filterStorage")); | 
| 38   callback(); | 42   callback(); | 
| 39 }; | 43 }; | 
| 40 | 44 | 
| 41 function compareSubscription(test, url, expected, postInit) | 45 function testEqualSubscriptions(test, value, expected) | 
| 42 { | 46 { | 
| 43   expected.push("[Subscription]"); | 47   testEqualObjProperties(test, value, expected, | 
|  | 48     { | 
|  | 49       filters(propValue, expectedPropValue, message) | 
|  | 50       { | 
|  | 51         let {filterCount} = expected; | 
|  | 52         test.equal(value.filterCount, filterCount, "Different number of filters"
     ); | 
|  | 53         for (let i = 0; i < filterCount; ++i) | 
|  | 54           withNAD([1, 2], testEqualObjProperties)(test, value.filterAt(i), expec
     ted.filterAt(i)); | 
|  | 55       } | 
|  | 56     }); | 
|  | 57 } | 
|  | 58 | 
|  | 59 function serializeSubscription(subscription) | 
|  | 60 { | 
|  | 61   let serializer = Serializer.create(); | 
|  | 62   try | 
|  | 63   { | 
|  | 64     serializer.serialize(subscription); | 
|  | 65     return serializer.data; | 
|  | 66   } | 
|  | 67   finally | 
|  | 68   { | 
|  | 69     serializer.delete(); | 
|  | 70   } | 
|  | 71 } | 
|  | 72 | 
|  | 73 function createSubscription(url, postInit) | 
|  | 74 { | 
| 44   let subscription = Subscription.fromURL(url); | 75   let subscription = Subscription.fromURL(url); | 
| 45   if (postInit) | 76   try | 
| 46     postInit(subscription); | 77   { | 
| 47   let result = subscription.serialize().trim().split("\n"); | 78     if (postInit) | 
| 48   test.equal(result.sort().join("\n"), expected.sort().join("\n"), url); | 79       postInit(subscription); | 
| 49   subscription.delete(); | 80   } | 
|  | 81   catch (ex) | 
|  | 82   { | 
|  | 83     subscription.delete(); | 
|  | 84     subscription = null; | 
|  | 85     throw ex; | 
|  | 86   } | 
|  | 87   return subscription; | 
|  | 88 } | 
|  | 89 | 
|  | 90 function testSerializeParse(test, subscription, processSerialized) | 
|  | 91 { | 
|  | 92   let serializedData = serializeSubscription(subscription); | 
|  | 93   if (processSerialized) | 
|  | 94     processSerialized(serializedData); | 
|  | 95   let parser = Parser.create(); | 
|  | 96   try | 
|  | 97   { | 
|  | 98     for (let line of serializedData.split("\n")) | 
|  | 99       parser.process(line); | 
|  | 100     parser.finalize(); | 
|  | 101     test.equal(parser.subscriptionCount, 1); | 
|  | 102     withNAD(1, testEqualSubscriptions)(test, parser.subscriptionAt(0), subscript
     ion); | 
|  | 103   } | 
|  | 104   finally | 
|  | 105   { | 
|  | 106     parser.delete(); | 
|  | 107   } | 
| 50 } | 108 } | 
| 51 | 109 | 
| 52 exports.testSubscriptionClassDefinitions = function(test) | 110 exports.testSubscriptionClassDefinitions = function(test) | 
| 53 { | 111 { | 
| 54   test.equal(typeof Subscription, "function", "typeof Subscription"); | 112   test.equal(typeof Subscription, "function", "typeof Subscription"); | 
| 55   test.equal(typeof SpecialSubscription, "function", "typeof SpecialSubscription
     "); | 113   test.equal(typeof SpecialSubscription, "function", "typeof SpecialSubscription
     "); | 
| 56   test.equal(typeof DownloadableSubscription, "function", "typeof DownloadableSu
     bscription"); | 114   test.equal(typeof DownloadableSubscription, "function", "typeof DownloadableSu
     bscription"); | 
| 57 | 115 | 
| 58   test.done(); | 116   test.done(); | 
| 59 }; | 117 }; | 
| 60 | 118 | 
| 61 exports.testSubscriptionsWithState = function(test) | 119 exports.testSerializationParsingPreservesSubscriptionProperties = function(test) | 
| 62 { | 120 { | 
| 63   compareSubscription(test, "~fl~", ["url=~fl~"]); | 121   let localTestSerializeParse = (url, postInit) => | 
| 64   compareSubscription(test, "http://test/default", ["url=http://test/default", "
     title=http://test/default"]); | 122     withNAD(1, testSerializeParse)(test, createSubscription(url, postInit)); | 
| 65   compareSubscription(test, "http://test/default_titled", ["url=http://test/defa
     ult_titled", "title=test"], subscription => | 123   localTestSerializeParse("~fl~"); | 
| 66   { | 124   localTestSerializeParse("http://test/default"); | 
| 67     subscription.title = "test"; | 125   localTestSerializeParse("http://test/default_titled", subscription => | 
| 68   }); | 126     subscription.title = "test" | 
| 69   compareSubscription(test, "http://test/non_default", [ | 127   ); | 
| 70     "url=http://test/non_default", "title=test", "fixedTitle=true", | 128   localTestSerializeParse("http://test/non_default", subscription => | 
| 71     "disabled=true", "lastSuccess=20015998341138", |  | 
| 72     "lastDownload=5124097847590911", "lastCheck=18446744069414584320", |  | 
| 73     "softExpiration=2682143778081159", "expires=4294967295", |  | 
| 74     "downloadStatus=foo", "errors=3", "version=24", "requiredVersion=0.6" |  | 
| 75   ], subscription => |  | 
| 76   { | 129   { | 
| 77     subscription.title = "test"; | 130     subscription.title = "test"; | 
| 78     subscription.fixedTitle = true; | 131     subscription.fixedTitle = true; | 
| 79     subscription.disabled = true; | 132     subscription.disabled = true; | 
| 80     subscription.lastSuccess = 20015998341138;       // 0x123456789012 | 133     subscription.lastSuccess = 20015998341138;       // 0x123456789012 | 
| 81     subscription.lastDownload = 5124097847590911;    // 0x123456FFFFFFFF | 134     subscription.lastDownload = 5124097847590911;    // 0x123456FFFFFFFF | 
| 82     subscription.lastCheck = 18446744069414584320;   // 0xFFFFFFFF00000000 | 135     subscription.lastCheck = 18446744069414584320;   // 0xFFFFFFFF00000000 | 
| 83     subscription.softExpiration = 2682143778081159;  // 0x9876543210987 | 136     subscription.softExpiration = 2682143778081159;  // 0x9876543210987 | 
| 84     subscription.expires = 4294967295;               // 0xFFFFFFFF | 137     subscription.expires = 4294967295;               // 0xFFFFFFFF | 
| 85     subscription.downloadStatus = "foo"; | 138     subscription.downloadStatus = "foo"; | 
| 86     subscription.errors = 3; | 139     subscription.errors = 3; | 
| 87     subscription.version = 24; | 140     subscription.version = 24; | 
| 88     subscription.requiredVersion = "0.6"; | 141     subscription.requiredVersion = "0.6"; | 
| 89   }); | 142   }); | 
| 90   compareSubscription(test, "~wl~", ["url=~wl~", "disabled=true", "title=Test gr
     oup"], subscription => | 143   localTestSerializeParse("~wl~", subscription => | 
| 91   { | 144   { | 
| 92     subscription.title = "Test group"; | 145     subscription.title = "Test group"; | 
| 93     subscription.disabled = true; | 146     subscription.disabled = true; | 
| 94   }); | 147   }); | 
| 95 | 148 | 
| 96   test.done(); | 149   test.done(); | 
| 97 }; | 150 }; | 
| 98 | 151 | 
| 99 exports.testDefaultSubscriptionIDs = function(test) | 152 exports.testDefaultSubscriptionIDs = function(test) | 
| 100 { | 153 { | 
| (...skipping 17 matching lines...) Expand all  Loading... | 
| 118   let tests = [ | 171   let tests = [ | 
| 119     ["blocking", "test"], | 172     ["blocking", "test"], | 
| 120     ["whitelist", "@@test"], | 173     ["whitelist", "@@test"], | 
| 121     ["elemhide", "##test"], | 174     ["elemhide", "##test"], | 
| 122     ["elemhide", "#@#test"], | 175     ["elemhide", "#@#test"], | 
| 123     ["elemhide", "foo##:-abp-properties(foo)"], | 176     ["elemhide", "foo##:-abp-properties(foo)"], | 
| 124     ["elemhide", "foo#?#:-abp-properties(foo)"], | 177     ["elemhide", "foo#?#:-abp-properties(foo)"], | 
| 125     // Invalid elemhide filter. Incorrectly classified as blocking. | 178     // Invalid elemhide filter. Incorrectly classified as blocking. | 
| 126     // See https://issues.adblockplus.org/ticket/6234 | 179     // See https://issues.adblockplus.org/ticket/6234 | 
| 127     ["blocking", "foo#@?#:-abp-properties(foo)"], | 180     ["blocking", "foo#@?#:-abp-properties(foo)"], | 
| 128     ["", "!test"], | 181     [null, "!test"], | 
| 129     ["", "/??/"], | 182     [null, "/??/"], | 
| 130     ["blocking whitelist", "test", "@@test"], | 183     ["blocking whitelist", "test", "@@test"], | 
| 131     ["blocking elemhide", "test", "##test"] | 184     ["blocking elemhide", "test", "##test"] | 
| 132   ]; | 185   ]; | 
| 133 | 186 | 
| 134   for (let [defaults, ...filters] of tests) | 187   for (let [defaults, ...filters] of tests) | 
| 135   { | 188   { | 
| 136     let expected = ["url=~user~" + filters.join("~")]; | 189     withNAD(1, testSerializeParse)(test, createSubscription("~user~" + filters.j
     oin("~"), | 
| 137     if (defaults) | 190       subscription => | 
| 138       expected.push("defaults= " + defaults); |  | 
| 139     compareSubscription(test, "~user~" + filters.join("~"), expected, subscripti
     on => |  | 
| 140     { |  | 
| 141       for (let text of filters) |  | 
| 142       { | 191       { | 
| 143         let filter = Filter.fromText(text); | 192         for (let text of filters) | 
| 144         subscription.makeDefaultFor(filter); | 193           withNAD(0, subscription.makeDefaultFor, subscription)(Filter.fromText(
     text)); | 
| 145         filter.delete(); | 194       }), (serializedData) => | 
| 146       } | 195       { | 
| 147     }); | 196         let foundDefaults = null; | 
|  | 197         for (let line of serializedData.split("\n")) | 
|  | 198         { | 
|  | 199           if (line.startsWith("defaults=")) | 
|  | 200           { | 
|  | 201             foundDefaults = line; | 
|  | 202             break; | 
|  | 203           } | 
|  | 204         } | 
|  | 205         test.equal(foundDefaults, defaults ? "defaults= " + defaults : null, "un
     expected serialization of defaults"); | 
|  | 206       }); | 
| 148   } | 207   } | 
| 149   test.done(); | 208   test.done(); | 
| 150 }; | 209 }; | 
| 151 | 210 | 
| 152 exports.testGC = function(test) | 211 exports.testGC = function(test) | 
| 153 { | 212 { | 
| 154   let subscription1 = Subscription.fromURL("http://example.com/"); | 213   let subscription1 = Subscription.fromURL("http://example.com/"); | 
| 155   test.equal(subscription1.lastDownload, 0, "Initial download time"); | 214   test.equal(subscription1.lastDownload, 0, "Initial download time"); | 
| 156 | 215 | 
| 157   subscription1.lastDownload = 432; | 216   subscription1.lastDownload = 432; | 
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 238   checkFilterAt(0, "filter2", "First filter after releasing filter references"); | 297   checkFilterAt(0, "filter2", "First filter after releasing filter references"); | 
| 239   checkFilterAt(1, "filter1", "Second filter after releasing filter references")
     ; | 298   checkFilterAt(1, "filter1", "Second filter after releasing filter references")
     ; | 
| 240 | 299 | 
| 241   subscription.delete(); | 300   subscription.delete(); | 
| 242 | 301 | 
| 243   test.done(); | 302   test.done(); | 
| 244 }; | 303 }; | 
| 245 | 304 | 
| 246 exports.testFilterSerialization = function(test) | 305 exports.testFilterSerialization = function(test) | 
| 247 { | 306 { | 
| 248   let filter1 = Filter.fromText("filter1"); | 307   withNAD([0, 1, 2], (subscription, filter1, filter2) => | 
| 249   let filter2 = Filter.fromText("filter2"); | 308   { | 
|  | 309     testSerializeParse(test, subscription, (serializedData) => | 
|  | 310       test.ok(!serializedData.includes("[Subscription filters]"), "Unexpected fi
     lters section") | 
|  | 311     ); | 
| 250 | 312 | 
| 251   let subscription = Subscription.fromURL("~user~12345"); | 313     subscription.insertFilterAt(filter1, 0); | 
| 252   test.equal(subscription.serializeFilters(), "", "No filters added"); | 314     subscription.insertFilterAt(filter1, 1); | 
|  | 315     subscription.insertFilterAt(filter2, 1); | 
| 253 | 316 | 
| 254   subscription.insertFilterAt(filter1, 0); | 317     testSerializeParse(test, subscription, (serializedData) => | 
| 255   subscription.insertFilterAt(filter1, 1); | 318       test.ok(serializedData.includes("[Subscription filters]\nfilter1\nfilter2\
     nfilter1\n"), "Three filters added") | 
| 256   subscription.insertFilterAt(filter2, 1); | 319     ); | 
| 257   test.equal(subscription.serializeFilters(), "[Subscription filters]\nfilter1\n
     filter2\nfilter1\n", "Three filters added"); |  | 
| 258 | 320 | 
| 259   subscription.removeFilterAt(0); | 321     subscription.removeFilterAt(0); | 
| 260   test.equal(subscription.serializeFilters(), "[Subscription filters]\nfilter2\n
     filter1\n", "One filter removed"); | 322     testSerializeParse(test, subscription, (serializedData) => | 
| 261 | 323       test.ok(serializedData.includes("[Subscription filters]\nfilter2\nfilter1\
     n"), "One filter removed") | 
| 262   subscription.delete(); | 324     ); | 
| 263   filter1.delete(); | 325   })(Subscription.fromURL("~user~12345"), Filter.fromText("filter1"), Filter.fro
     mText("filter2")); | 
| 264   filter2.delete(); |  | 
| 265 | 326 | 
| 266   test.done(); | 327   test.done(); | 
| 267 }; | 328 }; | 
| 268 | 329 | 
|  | 330 exports.testEscapingFilterSerialization = function(test) | 
|  | 331 { | 
|  | 332   withNAD(0, subscription => | 
|  | 333   { | 
|  | 334     let subsriptionAddFilter = withNAD(0, subscription.insertFilterAt, subscript
     ion); | 
|  | 335 | 
|  | 336     subsriptionAddFilter(Filter.fromText("[[x[x[[]x]"), 0); | 
|  | 337     subsriptionAddFilter(Filter.fromText("x[[x[x[[]x]x"), 1); | 
|  | 338     subsriptionAddFilter(Filter.fromText("x\\[]x"), 2); | 
|  | 339 | 
|  | 340     testSerializeParse(test, subscription, (serializedData) => | 
|  | 341       test.ok(serializedData.includes("[Subscription filters]\n\\[\\[x\\[x\\[\\[
     ]x]\nx\\[\\[x\\[x\\[\\[]x]x\nx\\\\[]x\n"), "Filters should be escaped")); | 
|  | 342   })(Subscription.fromURL("~user~12345")); | 
|  | 343   test.done(); | 
|  | 344 }; | 
|  | 345 | 
| 269 exports.testNotifications = function(test) | 346 exports.testNotifications = function(test) | 
| 270 { | 347 { | 
| 271   function checkNotifications(action, expected, message) | 348   function checkNotifications(action, expected, message) | 
| 272   { | 349   { | 
| 273     let result = null; | 350     let result = null; | 
| 274     let listener = (topic, subscription) => | 351     let listener = (topic, subscription) => | 
| 275     { | 352     { | 
| 276       if (result) | 353       if (result) | 
| 277         test.ok(false, "Got more that one notification - " + message); | 354         test.ok(false, "Got more that one notification - " + message); | 
| 278       else | 355       else | 
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 365     subscription.errors++; | 442     subscription.errors++; | 
| 366   }, ["subscription.errors", "http://example.com/"], "Increasing subscription.er
     rors"); | 443   }, ["subscription.errors", "http://example.com/"], "Increasing subscription.er
     rors"); | 
| 367   checkNotifications(() => | 444   checkNotifications(() => | 
| 368   { | 445   { | 
| 369     subscription.errors = 0; | 446     subscription.errors = 0; | 
| 370   }, ["subscription.errors", "http://example.com/"], "Resetting subscription.err
     ors"); | 447   }, ["subscription.errors", "http://example.com/"], "Resetting subscription.err
     ors"); | 
| 371 | 448 | 
| 372   subscription.delete(); | 449   subscription.delete(); | 
| 373   test.done(); | 450   test.done(); | 
| 374 }; | 451 }; | 
| OLD | NEW | 
|---|