| LEFT | RIGHT | 
|---|
| 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 {createSandbox} = require("./_common"); | 20 const {createSandbox} = require("./_common"); | 
|  | 21 const {withNAD} = require("./_test-utils"); | 
| 21 | 22 | 
| 22 let ElemHideEmulationFilter = null; | 23 let ElemHideEmulationFilter = null; | 
| 23 let ElemHideEmulation = null; | 24 let ElemHideEmulation = null; | 
| 24 let ElemHide = null; | 25 let ElemHide = null; | 
| 25 let Filter = null; | 26 let Filter = null; | 
| 26 | 27 | 
| 27 exports.setUp = function(callback) | 28 exports.setUp = function(callback) | 
| 28 { | 29 { | 
| 29   let sandboxedRequire = createSandbox(); | 30   let sandboxedRequire = createSandbox(); | 
| 30   ( | 31   ( | 
| 31     {Filter, | 32     {Filter, | 
| 32      ElemHideEmulationFilter} = sandboxedRequire("../lib/filterClasses"), | 33      ElemHideEmulationFilter} = sandboxedRequire("../lib/filterClasses"), | 
| 33     {ElemHideEmulation} = sandboxedRequire("../lib/elemHideEmulation"), | 34     {ElemHideEmulation} = sandboxedRequire("../lib/elemHideEmulation"), | 
| 34     {ElemHide} = sandboxedRequire("../lib/elemHide") | 35     {ElemHide} = sandboxedRequire("../lib/elemHide") | 
| 35   ); | 36   ); | 
| 36 | 37 | 
| 37   callback(); | 38   callback(); | 
| 38 }; | 39 }; | 
| 39 | 40 | 
| 40 exports.testElemHideAPI = function(test) | 41 exports.testElemHideAPI = function(test) | 
| 41 { | 42 { | 
|  | 43   withNAD(0, elemHide => | 
| 42   { | 44   { | 
| 43     let filter = Filter.fromText("###ads"); | 45     withNAD(0, filter => | 
| 44     ElemHide.add(filter); | 46     { | 
| 45 | 47       elemHide.add(filter); | 
| 46     test.equal(filter.selectorDomain, ""); | 48       test.equal(filter.selectorDomain, ""); | 
| 47     let unconditionals = ElemHide.getUnconditionalSelectors(); | 49     })(Filter.fromText("###ads")); | 
| 48     test.equal(unconditionals.selectorCount, 1); | 50 | 
| 49     test.equal(unconditionals.selectorAt(0), "#ads"); | 51     withNAD(0, unconditionals => | 
| 50     test.equal(unconditionals.filterKeyAt(0), "###ads"); | 52     { | 
| 51     filter.delete(); | 53       test.equal(unconditionals.selectorCount, 1); | 
| 52     unconditionals.delete(); | 54       test.equal(unconditionals.selectorAt(0), "#ads"); | 
| 53   } | 55       test.equal(unconditionals.filterKeyAt(0), "###ads"); | 
| 54 | 56     })(elemHide.getUnconditionalSelectors()); | 
| 55   { | 57 | 
| 56     let filter2 = Filter.fromText("example.com##.foo"); | 58     withNAD(0, filter => | 
| 57     ElemHide.add(filter2); | 59     { | 
| 58     test.equal(filter2.selectorDomain, "example.com"); | 60       elemHide.add(filter); | 
| 59     filter2.delete(); | 61       test.equal(filter.selectorDomain, "example.com"); | 
| 60   } | 62     })(Filter.fromText("example.com##.foo")); | 
| 61 | 63 | 
| 62   let unconditionals = ElemHide.getUnconditionalSelectors(); | 64     withNAD( | 
| 63   test.equal(unconditionals.selectorCount, 1); | 65       0, unconditionals => | 
| 64   unconditionals.delete(); | 66         test.equal(unconditionals.selectorCount, 1))(elemHide.getUnconditionalSe
     lectors()); | 
| 65 | 67 | 
| 66   let selectors = ElemHide.getSelectorsForDomain("example.com", 1); | 68     withNAD(0, selectors => | 
| 67   test.equal(selectors.selectorCount, 1); | 69     { | 
| 68   test.equal(selectors.selectorAt(0), ".foo"); | 70       test.equal(selectors.selectorCount, 1); | 
| 69   test.equal(selectors.filterKeyAt(0), "example.com##.foo"); | 71       test.equal(selectors.selectorAt(0), ".foo"); | 
| 70   selectors.delete(); | 72       test.equal(selectors.filterKeyAt(0), "example.com##.foo"); | 
| 71 | 73     })(elemHide.getSelectorsForDomain("example.com", 1)); | 
| 72   selectors = ElemHide.getSelectorsForDomain("example.com", 0); | 74 | 
| 73   test.equal(selectors.selectorCount, 2); | 75     withNAD(0, selectors => | 
| 74   test.equal(selectors.selectorAt(0), "#ads"); | 76     { | 
| 75   test.equal(selectors.filterKeyAt(0), "###ads"); | 77       test.equal(selectors.selectorCount, 2); | 
| 76   test.equal(selectors.selectorAt(1), ".foo"); | 78       test.equal(selectors.selectorAt(0), "#ads"); | 
| 77   test.equal(selectors.filterKeyAt(1), "example.com##.foo"); | 79       test.equal(selectors.filterKeyAt(0), "###ads"); | 
| 78   selectors.delete(); | 80       test.equal(selectors.selectorAt(1), ".foo"); | 
| 79 | 81       test.equal(selectors.filterKeyAt(1), "example.com##.foo"); | 
| 80   let filter3 = Filter.fromText("example.com##.message"); | 82     })(elemHide.getSelectorsForDomain("example.com", 0)); | 
| 81   ElemHide.add(filter3); | 83 | 
| 82   selectors = ElemHide.getSelectorsForDomain("example.com", 0); | 84     withNAD(0, filter3 => | 
| 83   test.equal(selectors.selectorCount, 3); | 85     { | 
| 84   selectors.delete(); | 86       elemHide.add(filter3); | 
| 85   selectors = ElemHide.getSelectorsForDomain("mail.example.com", 0); | 87 | 
| 86   test.equal(selectors.selectorCount, 3); | 88       withNAD( | 
| 87   selectors.delete(); | 89         0, selectors => | 
| 88 | 90         { | 
| 89   let filter4 = Filter.fromText("mail.example.com#@#.message"); | 91           test.equal(selectors.selectorCount, 3); | 
| 90   ElemHide.add(filter4); | 92           test.equal(selectors.selectorAt(0), "#ads"); | 
| 91   selectors = ElemHide.getSelectorsForDomain("example.com", 0); | 93           test.equal(selectors.selectorAt(1), ".message"); | 
| 92   test.equal(selectors.selectorCount, 3); | 94           test.equal(selectors.selectorAt(2), ".foo"); | 
| 93   selectors.delete(); | 95         })( | 
| 94   selectors = ElemHide.getSelectorsForDomain("mail.example.com", 0); | 96         elemHide.getSelectorsForDomain("example.com", 0)); | 
| 95   test.equal(selectors.selectorCount, 2); | 97 | 
| 96   selectors.delete(); | 98       withNAD( | 
| 97 | 99         0, selectors => | 
| 98   unconditionals = ElemHide.getUnconditionalSelectors(); | 100         { | 
| 99   test.equal(unconditionals.selectorCount, 1); | 101           test.equal(selectors.selectorCount, 3); | 
| 100   unconditionals.delete(); | 102           test.equal(selectors.selectorAt(0), "#ads"); | 
| 101 | 103           test.equal(selectors.selectorAt(1), ".message"); | 
| 102   ElemHide.remove(filter4); | 104           test.equal(selectors.selectorAt(2), ".foo"); | 
| 103   filter4.delete(); | 105         })( | 
| 104   selectors = ElemHide.getSelectorsForDomain("example.com", 0); | 106         elemHide.getSelectorsForDomain("mail.example.com", 0)); | 
| 105   test.equal(selectors.selectorCount, 3); | 107 | 
| 106   selectors.delete(); | 108       withNAD(0, filter4 => | 
| 107   selectors = ElemHide.getSelectorsForDomain("mail.example.com", 0); | 109       { | 
| 108   test.equal(selectors.selectorCount, 3); | 110         elemHide.add(filter4); | 
| 109   selectors.delete(); | 111         withNAD( | 
| 110 | 112           0, selectors => | 
| 111   ElemHide.remove(filter3); | 113           { | 
| 112   filter3.delete(); | 114             test.equal(selectors.selectorCount, 3); | 
| 113   selectors = ElemHide.getSelectorsForDomain("example.com", 0); | 115             test.equal(selectors.selectorAt(0), "#ads"); | 
| 114   test.equal(selectors.selectorCount, 2); | 116             test.equal(selectors.selectorAt(1), ".message"); | 
| 115   selectors.delete(); | 117             test.equal(selectors.selectorAt(2), ".foo"); | 
|  | 118           })( | 
|  | 119           elemHide.getSelectorsForDomain("example.com", 0)); | 
|  | 120 | 
|  | 121         withNAD( | 
|  | 122           0, selectors => | 
|  | 123           { | 
|  | 124             test.equal(selectors.selectorCount, 2); | 
|  | 125             test.equal(selectors.selectorAt(0), "#ads"); | 
|  | 126             test.equal(selectors.selectorAt(1), ".foo"); | 
|  | 127           })( | 
|  | 128           elemHide.getSelectorsForDomain("mail.example.com", 0)); | 
|  | 129 | 
|  | 130         withNAD( | 
|  | 131           0, | 
|  | 132           unconditionals => | 
|  | 133           { | 
|  | 134             test.equal(unconditionals.selectorCount, 1); | 
|  | 135             test.equal(unconditionals.selectorAt(0), "#ads"); | 
|  | 136           })(elemHide.getUnconditionalSelectors()); | 
|  | 137 | 
|  | 138         elemHide.remove(filter4); | 
|  | 139       })(Filter.fromText("mail.example.com#@#.message")); | 
|  | 140 | 
|  | 141       withNAD( | 
|  | 142         0, selectors => | 
|  | 143         { | 
|  | 144           test.equal(selectors.selectorCount, 3); | 
|  | 145           test.equal(selectors.selectorAt(0), "#ads"); | 
|  | 146           test.equal(selectors.selectorAt(1), ".message"); | 
|  | 147           test.equal(selectors.selectorAt(2), ".foo"); | 
|  | 148         })(elemHide.getSelectorsForDomain("example.com", 0)); | 
|  | 149 | 
|  | 150       withNAD( | 
|  | 151         0, selectors => | 
|  | 152         { | 
|  | 153           test.equal(selectors.selectorCount, 3); | 
|  | 154           test.equal(selectors.selectorAt(0), "#ads"); | 
|  | 155           test.equal(selectors.selectorAt(1), ".message"); | 
|  | 156           test.equal(selectors.selectorAt(2), ".foo"); | 
|  | 157         })(elemHide.getSelectorsForDomain("mail.example.com", 0)); | 
|  | 158 | 
|  | 159       elemHide.remove(filter3); | 
|  | 160     })(Filter.fromText("example.com##.message")); | 
|  | 161 | 
|  | 162     withNAD( | 
|  | 163       0, selectors => | 
|  | 164         test.equal(selectors.selectorCount, 2))( | 
|  | 165       elemHide.getSelectorsForDomain("example.com", 0)); | 
|  | 166   })(ElemHide.create()); | 
| 116 | 167 | 
| 117   test.done(); | 168   test.done(); | 
| 118 }; | 169 }; | 
| 119 | 170 | 
| 120 exports.testSyntaxConversion = function(test) | 171 exports.testSyntaxConversion = function(test) | 
| 121 { | 172 { | 
| 122   function checkConvertedFilter(old, converted) | 173   function checkConvertedFilter(old, converted) | 
| 123   { | 174   { | 
| 124     let filter = Filter.fromText(old); | 175     withNAD( | 
| 125 | 176       0, filter => test.equal(filter.text, converted))(Filter.fromText(old)); | 
| 126     test.equal(filter.text, converted); |  | 
| 127   } | 177   } | 
| 128 | 178 | 
| 129   checkConvertedFilter("example.com#?#foo[-abp-properties='something']bar", "exa
     mple.com#?#foo:-abp-properties(something)bar"); | 179   checkConvertedFilter("example.com##foo[-abp-properties='something']bar", "exam
     ple.com#?#foo:-abp-properties(something)bar"); | 
| 130   checkConvertedFilter("example.com#@#foo[-abp-properties='something']bar", "exa
     mple.com#@#foo:-abp-properties(something)bar"); | 180   checkConvertedFilter("example.com#@#foo[-abp-properties='something']bar", "exa
     mple.com#@#foo:-abp-properties(something)bar"); | 
| 131   checkConvertedFilter("example.com#?#[-abp-properties=\"something\"]", "example
     .com#?#:-abp-properties(something)"); | 181   checkConvertedFilter("example.com##[-abp-properties=\"something\"]", "example.
     com#?#:-abp-properties(something)"); | 
| 132   checkConvertedFilter("example.com#?#[-abp-properties=(something)]", "example.c
     om#?#:-abp-properties((something))"); | 182   checkConvertedFilter("example.com##[-abp-properties='(something)']", "example.
     com#?#:-abp-properties((something))"); | 
| 133 | 183 | 
| 134   test.done(); | 184   test.done(); | 
| 135 }; | 185 }; | 
| 136 | 186 | 
| 137 exports.testDomainRestrictions = function(test) | 187 exports.testDomainRestrictions = function(test) | 
| 138 { | 188 { | 
| 139   function testSelectorMatches(description, filters, domain, expectedMatches) | 189   function testSelectorMatches(description, filters, domain, expectedMatches) | 
| 140   { | 190   { | 
| 141     for (let text of filters) | 191     withNAD([0, 1], (elemHide, elemHideEmulation) => | 
| 142     { | 192     { | 
| 143       let filter = Filter.fromText(text); | 193       let addFilter = withNAD(0, filter => | 
| 144       if (filter instanceof ElemHideEmulationFilter) | 194       { | 
| 145         ElemHideEmulation.add(filter); | 195         if (filter instanceof ElemHideEmulationFilter) | 
| 146       else | 196           elemHideEmulation.add(filter); | 
| 147         ElemHide.add(filter); | 197         else | 
| 148       filter.delete(); | 198           elemHide.add(filter); | 
| 149     } | 199       }); | 
| 150 | 200 | 
| 151     let rules = ElemHideEmulation.getRulesForDomain(domain); | 201       for (let text of filters) | 
| 152     let matches = []; | 202         addFilter(Filter.fromText(text)); | 
| 153     for (let i = 0; i < rules.filterCount; i++) | 203 | 
| 154     { | 204       withNAD(0, rules => | 
| 155       let filter = rules.filterAt(i); | 205       { | 
| 156       matches.push(filter.text); | 206         let matches = []; | 
| 157       filter.delete(); | 207         let push = withNAD(0, filter => matches.push(filter.text)); | 
| 158     } | 208 | 
| 159     test.deepEqual(matches.sort(), expectedMatches.sort(), description); | 209         for (let i = 0; i < rules.filterCount; i++) | 
| 160     rules.delete(); | 210           push(rules.filterAt(i)); | 
| 161 | 211 | 
| 162     ElemHideEmulation.clear(); | 212         test.deepEqual(matches.sort(), expectedMatches.sort(), description); | 
| 163     ElemHide.clear(); | 213       })(elemHideEmulation.getRulesForDomain(elemHide, domain)); | 
|  | 214 | 
|  | 215       elemHideEmulation.clear(); | 
|  | 216     })(ElemHide.create(), ElemHideEmulation.create()); | 
| 164   } | 217   } | 
| 165 | 218 | 
| 166   testSelectorMatches( | 219   testSelectorMatches( | 
| 167     "Ignore generic filters", | 220     "Ignore generic filters", | 
| 168     [ | 221     [ | 
| 169       "#?#:-abp-properties(foo)", "example.com#?#:-abp-properties(foo)", | 222       "#?#:-abp-properties(foo)", "example.com#?#:-abp-properties(foo)", | 
| 170       "~example.com##:-abp-properties(foo)" | 223       "~example.com##:-abp-properties(foo)" | 
| 171     ], | 224     ], | 
| 172     "example.com", | 225     "example.com", | 
| 173     ["example.com#?#:-abp-properties(foo)"] | 226     ["example.com#?#:-abp-properties(foo)"] | 
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 207     ], | 260     ], | 
| 208     "other.example.com", | 261     "other.example.com", | 
| 209     ["other.example.com#?#:-abp-properties(foo)"] | 262     ["other.example.com#?#:-abp-properties(foo)"] | 
| 210   ); | 263   ); | 
| 211 | 264 | 
| 212   test.done(); | 265   test.done(); | 
| 213 }; | 266 }; | 
| 214 | 267 | 
| 215 exports.testElemHideEmulationFiltersContainer = function(test) | 268 exports.testElemHideEmulationFiltersContainer = function(test) | 
| 216 { | 269 { | 
| 217   function compareRules(description, domain, expectedMatches) | 270   withNAD([0, 1], (elemHide, elemHideEmulation) => | 
| 218   { | 271   { | 
| 219     let rules = ElemHideEmulation.getRulesForDomain(domain); | 272     function compareRules(description, domain, expectedMatches) | 
| 220     let result = []; | 273     { | 
| 221     for (let i = 0; i < rules.filterCount; i++) | 274       withNAD(0, rules => | 
| 222     { | 275       { | 
| 223       let filter = rules.filterAt(i); | 276         let result = []; | 
| 224       result.push(filter.text); | 277         for (let i = 0; i < rules.filterCount; i++) | 
| 225       filter.delete(); | 278           withNAD(0, filter => result.push(filter.text))(rules.filterAt(i)); | 
|  | 279 | 
|  | 280         expectedMatches = expectedMatches.map(filter => filter.text); | 
|  | 281         test.deepEqual(result.sort(), expectedMatches.sort(), description); | 
|  | 282       })(elemHideEmulation.getRulesForDomain(elemHide, domain)); | 
| 226     } | 283     } | 
| 227     expectedMatches = expectedMatches.map(filter => filter.text); | 284 | 
| 228     test.deepEqual(result.sort(), expectedMatches.sort(), description); | 285     withNAD([0, 1, 2], (domainFilter, subdomainFilter, otherDomainFilter) => | 
| 229 | 286     { | 
| 230     rules.delete(); | 287       elemHideEmulation.add(domainFilter); | 
| 231   } | 288       elemHideEmulation.add(subdomainFilter); | 
| 232 | 289       elemHideEmulation.add(otherDomainFilter); | 
| 233   let domainFilter = Filter.fromText("example.com##filter1"); | 290       compareRules( | 
| 234   let subdomainFilter = Filter.fromText("www.example.com##filter2"); | 291         "Return all matching filters", | 
| 235   let otherDomainFilter = Filter.fromText("other.example.com##filter3"); | 292         "www.example.com", | 
| 236 | 293         [domainFilter, subdomainFilter] | 
| 237   ElemHideEmulation.add(domainFilter); | 294       ); | 
| 238   ElemHideEmulation.add(subdomainFilter); | 295 | 
| 239   ElemHideEmulation.add(otherDomainFilter); | 296       elemHideEmulation.remove(domainFilter); | 
| 240   compareRules( | 297       compareRules( | 
| 241     "Return all matching filters", | 298         "Return all matching filters after removing one", | 
| 242     "www.example.com", | 299         "www.example.com", | 
| 243     [domainFilter, subdomainFilter] | 300         [subdomainFilter] | 
| 244   ); | 301       ); | 
| 245 | 302 | 
| 246   ElemHideEmulation.remove(domainFilter); | 303       elemHideEmulation.clear(); | 
| 247   compareRules( | 304       compareRules( | 
| 248     "Return all matching filters after removing one", | 305         "Return no filters after clearing", | 
| 249     "www.example.com", | 306         "www.example.com", | 
| 250     [subdomainFilter] | 307         [] | 
| 251   ); | 308       ); | 
| 252 | 309     })(Filter.fromText("example.com##filter1"), | 
| 253   ElemHideEmulation.clear(); | 310        Filter.fromText("www.example.com##filter2"), | 
| 254   compareRules( | 311        Filter.fromText("other.example.com##filter3")); | 
| 255     "Return no filters after clearing", | 312   })(ElemHide.create(), ElemHideEmulation.create()); | 
| 256     "www.example.com", |  | 
| 257     [] |  | 
| 258   ); |  | 
| 259 | 313 | 
| 260   test.done(); | 314   test.done(); | 
| 261 }; | 315 }; | 
| LEFT | RIGHT | 
|---|