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-2017 eyeo GmbH | 3 * Copyright (C) 2006-2017 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 Filter = require("filterClasses").Filter; | 20 let Filter = require("filterClasses").Filter; |
21 let ContentBlockerList = require("../lib/abp2blocklist.js").ContentBlockerList; | 21 let ContentBlockerList = require("../lib/abp2blocklist.js").ContentBlockerList; |
22 | 22 |
23 function testRules(test, filters, expected, transformFunction) | 23 function runTest(test, assertions) |
24 { | 24 { |
25 let blockerList = new ContentBlockerList(); | 25 // All the assertions are run in parallel but we wait for all of them to |
| 26 // finish before moving on to the next test. |
| 27 test.expect(assertions.length); |
| 28 Promise.all(assertions).then(() => test.done()); |
| 29 } |
| 30 |
| 31 function testRules(test, filters, expected, transformFunction, options) |
| 32 { |
| 33 let blockerList = new ContentBlockerList(options); |
26 for (let filter of filters) | 34 for (let filter of filters) |
27 blockerList.addFilter(Filter.fromText(filter)); | 35 blockerList.addFilter(Filter.fromText(filter)); |
28 | 36 |
29 let rules = blockerList.generateRules(); | 37 return blockerList.generateRules().then(rules => |
30 if (transformFunction) | 38 { |
31 rules = transformFunction(rules); | 39 if (transformFunction) |
32 | 40 rules = transformFunction(rules); |
33 test.deepEqual(rules, expected); | 41 |
| 42 test.deepEqual(rules, expected); |
| 43 }); |
34 } | 44 } |
35 | 45 |
36 exports.generateRules = { | 46 exports.generateRules = { |
37 testElementHiding: function(test) | 47 testElementHiding: function(test) |
38 { | 48 { |
39 testRules(test, ["##.whatever"], [ | 49 runTest(test, [ |
40 {trigger: {"url-filter": "^https?://", | 50 testRules(test, ["##.whatever"], [ |
41 "url-filter-is-case-sensitive": true}, | 51 {trigger: {"url-filter": "^https?://", |
42 action: {type: "css-display-none", selector: ".whatever"}} | 52 "url-filter-is-case-sensitive": true}, |
43 ]); | 53 action: {type: "css-display-none", selector: ".whatever"}} |
44 testRules(test, ["test.com##.whatever"], [ | 54 ]), |
45 {trigger: {"url-filter": "^https?://([^/:]*\\.)?test\\.com[/:]", | 55 testRules(test, ["test.com##.whatever"], [ |
46 "url-filter-is-case-sensitive": true}, | 56 {trigger: {"url-filter": "^https?://([^/:]*\\.)?test\\.com[/:]", |
47 action: {type: "css-display-none", selector: ".whatever"}} | 57 "url-filter-is-case-sensitive": true}, |
48 ]); | 58 action: {type: "css-display-none", selector: ".whatever"}} |
49 | 59 ]) |
50 test.done(); | 60 ]); |
51 }, | 61 }, |
52 | 62 |
53 testElementHidingExceptions: function(test) | 63 testElementHidingExceptions: function(test) |
54 { | 64 { |
55 testRules(test, [ | 65 runTest(test, [ |
56 "##.whatever", | 66 testRules(test, [ |
57 "test.com,anothertest.com###something", | 67 "##.whatever", |
58 "@@||special.test.com^$elemhide", | 68 "test.com,anothertest.com###something", |
59 "@@||test.com^$generichide", | 69 "@@||special.test.com^$elemhide", |
60 "@@||anothertest.com^$elemhide", | 70 "@@||test.com^$generichide", |
61 "@@^something^$elemhide", | 71 "@@||anothertest.com^$elemhide", |
62 "@@^anything^$generichide" | 72 "@@^something^$elemhide", |
63 ], [ | 73 "@@^anything^$generichide" |
64 ["^https?://", ["*test.com", "*special.test.com", "*anothertest.com"]], | 74 ], [ |
65 ["^https?://([^/:]*\\.)?test\\.com[/:]", ["*special.test.com"]] | 75 ["^https?://", ["*test.com", "*special.test.com", "*anothertest.com"]], |
66 ], rules => rules.map(rule => [rule.trigger["url-filter"], | 76 ["^https?://([^/:]*\\.)?test\\.com[/:]", ["*special.test.com"]] |
67 rule.trigger["unless-domain"]])); | 77 ], rules => rules.map(rule => [rule.trigger["url-filter"], |
68 | 78 rule.trigger["unless-domain"]])), |
69 testRules(test, ["#@#whatever"], []); | 79 |
70 testRules(test, ["test.com#@#whatever"], []); | 80 testRules(test, ["#@#whatever"], []), |
71 testRules(test, ["~test.com#@#whatever"], []); | 81 testRules(test, ["test.com#@#whatever"], []), |
72 | 82 testRules(test, ["~test.com#@#whatever"], []), |
73 // We currently completely ignore any element hiding filters that have the | 83 |
74 // same selector as an element hiding exception. In these examples #whatever | 84 // We currently completely ignore any element hiding filters that have the |
75 // should be hidden for all domains not ending in test.com instead of | 85 // same selector as an element hiding exception. In these examples |
76 // nowhere! | 86 // #whatever should be hidden for all domains not ending in test.com |
77 testRules(test, ["test.com#@#whatever", "##whatever"], []); | 87 // instead of nowhere! |
78 testRules(test, ["~test.com##whatever"], []); | 88 testRules(test, ["test.com#@#whatever", "##whatever"], []), |
79 | 89 testRules(test, ["~test.com##whatever"], []) |
80 test.done(); | 90 ]); |
81 }, | 91 }, |
82 | 92 |
83 testRequestFilters: function(test) | 93 testRequestFilters: function(test) |
84 { | 94 { |
85 testRules(test, [ | 95 runTest(test, [ |
86 "/foo", "||test.com^", "http://example.com/foo", "^foo^" | 96 testRules(test, [ |
87 ], [ | 97 "/foo", "||test.com^", "http://example.com/foo", "^foo^" |
88 { | 98 ], [ |
89 trigger: { | 99 { |
90 "url-filter": "^[^:]+:(//)?.*/foo", | 100 trigger: { |
91 "resource-type": ["image", "style-sheet", "script", "font", | 101 "url-filter": "^[^:]+:(//)?.*/foo", |
92 "media", "raw"] | 102 "resource-type": ["image", "style-sheet", "script", "font", |
| 103 "media", "raw"] |
| 104 }, |
| 105 action: {type: "block"} |
93 }, | 106 }, |
94 action: {type: "block"} | 107 { |
95 }, | 108 trigger: { |
96 { | 109 "url-filter": |
97 trigger: { | 110 "^[^:]+:(//)?([^/]+\\.)?test\\.com([^-_.%a-z0-9].*)?$", |
98 "url-filter": "^[^:]+:(//)?([^/]+\\.)?test\\.com([^-_.%a-z0-9].*)?$", | 111 "url-filter-is-case-sensitive": true, |
99 "url-filter-is-case-sensitive": true, | 112 "resource-type": ["image", "style-sheet", "script", "font", |
100 "resource-type": ["image", "style-sheet", "script", "font", | 113 "media", "raw", "document"], |
101 "media", "raw", "document"], | 114 "unless-top-url": [ |
102 "unless-top-url": [ | 115 "^[^:]+:(//)?([^/]+\\.)?test\\.com([^-_.%a-z0-9].*)?$" |
103 "^[^:]+:(//)?([^/]+\\.)?test\\.com([^-_.%a-z0-9].*)?$" | 116 ], |
104 ], | 117 "top-url-filter-is-case-sensitive": true |
105 "top-url-filter-is-case-sensitive": true | 118 }, |
| 119 action: {type: "block"} |
106 }, | 120 }, |
107 action: {type: "block"} | 121 { |
108 }, | 122 trigger: { |
109 { | 123 "url-filter": "^http://example\\.com/foo", |
110 trigger: { | 124 "resource-type": ["image", "style-sheet", "script", "font", |
111 "url-filter": "^http://example\\.com/foo", | 125 "media", "raw", "document"], |
112 "resource-type": ["image", "style-sheet", "script", "font", | 126 "unless-top-url": ["^http://example\\.com/foo"] |
113 "media", "raw", "document"], | 127 }, |
114 "unless-top-url": ["^http://example\\.com/foo"] | 128 action: {type: "block"} |
115 }, | 129 }, |
116 action: {type: "block"} | 130 { |
117 }, | 131 trigger: { |
118 { | 132 "url-filter": "^[^:]+:(//)?.*http://example\\.com/foo", |
119 trigger: { | 133 "resource-type": ["image", "style-sheet", "script", "font", |
120 "url-filter": "^[^:]+:(//)?.*http://example\\.com/foo", | 134 "media", "raw", "document"], |
121 "resource-type": ["image", "style-sheet", "script", "font", | 135 "unless-top-url": ["^[^:]+:(//)?.*http://example\\.com/foo"] |
122 "media", "raw", "document"], | 136 }, |
123 "unless-top-url": ["^[^:]+:(//)?.*http://example\\.com/foo"] | 137 action: {type: "block"} |
124 }, | 138 }, |
125 action: {type: "block"} | 139 { |
126 }, | 140 trigger: { |
127 { | 141 "url-filter": |
128 trigger: { | 142 "^[^:]+:(//)?(.*[^-_.%A-Za-z0-9])?foo([^-_.%A-Za-z0-9].*)?$", |
129 "url-filter": | 143 "resource-type": ["image", "style-sheet", "script", "font", |
130 "^[^:]+:(//)?(.*[^-_.%A-Za-z0-9])?foo([^-_.%A-Za-z0-9].*)?$", | 144 "media", "raw"] |
131 "resource-type": ["image", "style-sheet", "script", "font", | 145 }, |
132 "media", "raw"] | 146 action: {type: "block"} |
| 147 } |
| 148 ]), |
| 149 |
| 150 testRules(test, ["||example.com"], [ |
| 151 {trigger: {"url-filter": "^[^:]+:(//)?([^/]+\\.)?example\\.com", |
| 152 "url-filter-is-case-sensitive": true, |
| 153 "resource-type": ["image", "style-sheet", "script", "font", |
| 154 "media", "raw", "document"], |
| 155 "unless-top-url": ["^[^:]+:(//)?([^/]+\\.)?example\\.com"], |
| 156 "top-url-filter-is-case-sensitive": true}, |
| 157 |
| 158 action: {type: "block"}} |
| 159 ]), |
| 160 |
| 161 // Rules which would match no resource-types shouldn't be generated. |
| 162 testRules(test, ["foo$document", "||foo.com$document"], []) |
| 163 ]); |
| 164 }, |
| 165 |
| 166 testRequestFilterExceptions: function(test) |
| 167 { |
| 168 runTest(test, [ |
| 169 testRules(test, ["@@example.com"], [ |
| 170 {trigger: {"url-filter": "^[^:]+:(//)?.*example\\.com", |
| 171 "resource-type": ["image", "style-sheet", "script", "font", |
| 172 "media", "raw", "document"]}, |
| 173 action: {type: "ignore-previous-rules"}} |
| 174 ]), |
| 175 |
| 176 testRules(test, ["@@||example.com"], [ |
| 177 {trigger: {"url-filter": "^[^:]+:(//)?([^/]+\\.)?example\\.com", |
| 178 "url-filter-is-case-sensitive": true, |
| 179 "resource-type": ["image", "style-sheet", "script", "font", |
| 180 "media", "raw", "document"]}, |
| 181 action: {type: "ignore-previous-rules"}} |
| 182 ]) |
| 183 ]); |
| 184 }, |
| 185 |
| 186 testElementIDattributeFormat: function(test) |
| 187 { |
| 188 runTest(test, [ |
| 189 testRules(test, |
| 190 ["###example", "test.com###EXAMPLE"], |
| 191 ["[id=example]", "[id=EXAMPLE]"], |
| 192 rules => rules.map(rule => rule.action.selector)) |
| 193 ]); |
| 194 }, |
| 195 |
| 196 testDomainWhitelisting: function(test) |
| 197 { |
| 198 runTest(test, [ |
| 199 testRules(test, ["@@||example.com^$document"], [ |
| 200 { |
| 201 trigger: { |
| 202 "url-filter": ".*", |
| 203 "if-domain": ["*example.com"] |
| 204 }, |
| 205 action: {type: "ignore-previous-rules"} |
| 206 } |
| 207 ]), |
| 208 testRules(test, ["@@||example.com^$document,image"], [ |
| 209 { |
| 210 trigger: { |
| 211 "url-filter": ".*", |
| 212 "if-domain": ["*example.com"] |
| 213 }, |
| 214 action: {type: "ignore-previous-rules"} |
133 }, | 215 }, |
134 action: {type: "block"} | 216 { |
135 } | 217 trigger: { |
136 ]); | 218 "url-filter": |
137 | 219 "^https?://([^/]+\\.)?example\\.com([^-_.%a-z0-9].*)?$", |
138 testRules(test, ["||example.com"], [ | 220 "url-filter-is-case-sensitive": true, |
139 {trigger: {"url-filter": "^[^:]+:(//)?([^/]+\\.)?example\\.com", | 221 "resource-type": ["image"] |
140 "url-filter-is-case-sensitive": true, | 222 }, |
141 "resource-type": ["image", "style-sheet", "script", "font", | 223 action: {type: "ignore-previous-rules"} |
142 "media", "raw", "document"], | 224 } |
143 "unless-top-url": ["^[^:]+:(//)?([^/]+\\.)?example\\.com"], | 225 ]), |
144 "top-url-filter-is-case-sensitive": true}, | 226 testRules(test, ["@@||example.com/path^$font,document"], [ |
145 | 227 { |
146 action: {type: "block"}} | 228 trigger: { |
147 ]); | 229 "url-filter": |
148 | 230 "^https?://([^/]+\\.)?example\\.com/path([^-_.%A-Za-z0-9].*)?$", |
149 // Rules which would match no resource-types shouldn't be generated. | 231 "resource-type": ["font"] |
150 testRules(test, ["foo$document", "||foo.com$document"], []); | 232 }, |
151 | 233 action: {type: "ignore-previous-rules"} |
152 test.done(); | 234 } |
153 }, | 235 ]) |
154 | 236 ]); |
155 testRequestFilterExceptions: function(test) | |
156 { | |
157 testRules(test, ["@@example.com"], [ | |
158 {trigger: {"url-filter": "^[^:]+:(//)?.*example\\.com", | |
159 "resource-type": ["image", "style-sheet", "script", "font", | |
160 "media", "raw", "document"]}, | |
161 action: {type: "ignore-previous-rules"}} | |
162 ]); | |
163 | |
164 testRules(test, ["@@||example.com"], [ | |
165 {trigger: {"url-filter": "^[^:]+:(//)?([^/]+\\.)?example\\.com", | |
166 "url-filter-is-case-sensitive": true, | |
167 "resource-type": ["image", "style-sheet", "script", "font", | |
168 "media", "raw", "document"]}, | |
169 action: {type: "ignore-previous-rules"}} | |
170 ]); | |
171 | |
172 test.done(); | |
173 }, | |
174 | |
175 testElementIDattributeFormat: function(test) | |
176 { | |
177 testRules(test, | |
178 ["###example", "test.com###EXAMPLE"], | |
179 ["[id=example]", "[id=EXAMPLE]"], | |
180 rules => rules.map(rule => rule.action.selector)); | |
181 | |
182 test.done(); | |
183 }, | |
184 | |
185 testDomainWhitelisting: function(test) | |
186 { | |
187 testRules(test, ["@@||example.com^$document"], [ | |
188 { | |
189 trigger: { | |
190 "url-filter": ".*", | |
191 "if-domain": ["*example.com"] | |
192 }, | |
193 action: {type: "ignore-previous-rules"} | |
194 } | |
195 ]); | |
196 testRules(test, ["@@||example.com^$document,image"], [ | |
197 { | |
198 trigger: { | |
199 "url-filter": ".*", | |
200 "if-domain": ["*example.com"] | |
201 }, | |
202 action: {type: "ignore-previous-rules"} | |
203 }, | |
204 { | |
205 trigger: { | |
206 "url-filter": "^https?://([^/]+\\.)?example\\.com([^-_.%a-z0-9].*)?$", | |
207 "url-filter-is-case-sensitive": true, | |
208 "resource-type": ["image"] | |
209 }, | |
210 action: {type: "ignore-previous-rules"} | |
211 } | |
212 ]); | |
213 testRules(test, ["@@||example.com/path^$font,document"], [ | |
214 { | |
215 trigger: { | |
216 "url-filter": | |
217 "^https?://([^/]+\\.)?example\\.com/path([^-_.%A-Za-z0-9].*)?$", | |
218 "resource-type": ["font"] | |
219 }, | |
220 action: {type: "ignore-previous-rules"} | |
221 } | |
222 ]); | |
223 | |
224 test.done(); | |
225 }, | 237 }, |
226 | 238 |
227 testGenericblockExceptions: function(test) | 239 testGenericblockExceptions: function(test) |
228 { | 240 { |
229 testRules(test, ["^ad.jpg|", "@@||example.com^$genericblock"], | 241 runTest(test, [ |
230 [[undefined, ["*example.com"]]], | 242 testRules(test, ["^ad.jpg|", "@@||example.com^$genericblock"], |
231 rules => rules.map(rule => [rule.trigger["if-domain"], | 243 [[undefined, ["*example.com"]]], |
232 rule.trigger["unless-domain"]])); | 244 rules => rules.map(rule => [rule.trigger["if-domain"], |
233 testRules(test, ["^ad.jpg|$domain=test.com", | 245 rule.trigger["unless-domain"]])), |
234 "@@||example.com^$genericblock"], | 246 testRules(test, ["^ad.jpg|$domain=test.com", |
235 [[["*test.com"], undefined]], | 247 "@@||example.com^$genericblock"], |
236 rules => rules.map(rule => [rule.trigger["if-domain"], | 248 [[["*test.com"], undefined]], |
237 rule.trigger["unless-domain"]])); | 249 rules => rules.map(rule => [rule.trigger["if-domain"], |
238 testRules(test, ["^ad.jpg|$domain=~test.com", | 250 rule.trigger["unless-domain"]])), |
239 "@@||example.com^$genericblock"], | 251 testRules(test, ["^ad.jpg|$domain=~test.com", |
240 [[undefined, ["*test.com", "*example.com"]]], | 252 "@@||example.com^$genericblock"], |
241 rules => rules.map(rule => [rule.trigger["if-domain"], | 253 [[undefined, ["*test.com", "*example.com"]]], |
242 rule.trigger["unless-domain"]])); | 254 rules => rules.map(rule => [rule.trigger["if-domain"], |
243 | 255 rule.trigger["unless-domain"]])) |
244 test.done(); | 256 ]); |
245 }, | 257 }, |
246 | 258 |
247 testRuleOrdering: function(test) | 259 testRuleOrdering: function(test) |
248 { | 260 { |
249 testRules( | 261 runTest(test, [ |
250 test, | 262 testRules( |
251 ["/ads.jpg", "@@example.com", "test.com#@#foo", "##bar"], | 263 test, |
252 ["css-display-none", "block", "ignore-previous-rules"], | 264 ["/ads.jpg", "@@example.com", "test.com#@#foo", "##bar"], |
253 rules => rules.map(rule => rule.action.type) | 265 ["css-display-none", "block", "ignore-previous-rules"], |
254 ); | 266 rules => rules.map(rule => rule.action.type) |
255 testRules( | 267 ), |
256 test, | 268 testRules( |
257 ["@@example.com", "##bar", "/ads.jpg", "test.com#@#foo"], | 269 test, |
258 ["css-display-none", "block", "ignore-previous-rules"], | 270 ["@@example.com", "##bar", "/ads.jpg", "test.com#@#foo"], |
259 rules => rules.map(rule => rule.action.type) | 271 ["css-display-none", "block", "ignore-previous-rules"], |
260 ); | 272 rules => rules.map(rule => rule.action.type) |
261 | 273 ) |
262 test.done(); | 274 ]); |
263 }, | 275 }, |
264 | 276 |
265 testRequestTypeMapping: function(test) | 277 testRequestTypeMapping: function(test) |
266 { | 278 { |
267 testRules( | 279 runTest(test, [ |
268 test, | 280 testRules( |
269 ["1", "2$image", "3$stylesheet", "4$script", "5$font", "6$media", | 281 test, |
270 "7$popup", "8$object", "9$object_subrequest", "10$xmlhttprequest", | 282 ["1", "2$image", "3$stylesheet", "4$script", "5$font", "6$media", |
271 "11$websocket", "12$webrtc", | 283 "7$popup", "8$object", "9$object_subrequest", "10$xmlhttprequest", |
272 "13$ping", "14$subdocument", "15$other", "16$IMAGE", | 284 "11$websocket", "12$webrtc", |
273 "17$script,PING,Popup", "18$~image"], | 285 "13$ping", "14$subdocument", "15$other", "16$IMAGE", |
274 [["image", "style-sheet", "script", "font", "media", "raw"], | 286 "17$script,PING,Popup", "18$~image"], |
275 ["image"], | 287 [["image", "style-sheet", "script", "font", "media", "raw"], |
276 ["style-sheet"], | 288 ["image"], |
277 ["script"], | 289 ["style-sheet"], |
278 ["font"], | 290 ["script"], |
279 ["media"], | 291 ["font"], |
280 ["popup"], | 292 ["media"], |
281 ["media"], | 293 ["popup"], |
282 ["raw"], | 294 ["media"], |
283 ["raw"], | 295 ["raw"], |
284 ["raw"], // WebSocket | 296 ["raw"], |
285 ["raw"], // WebRTC: STUN | 297 ["raw"], // WebSocket |
286 ["raw"], // WebRTC: TURN | 298 ["raw"], // WebRTC: STUN |
287 ["raw"], | 299 ["raw"], // WebRTC: TURN |
288 ["raw"], | 300 ["raw"], |
289 ["image"], | 301 ["raw"], |
290 ["script", "popup", "raw" ], | 302 ["image"], |
291 ["style-sheet", "script", "font", "media", "raw"]], | 303 ["script", "popup", "raw" ], |
292 rules => rules.map(rule => rule.trigger["resource-type"]) | 304 ["style-sheet", "script", "font", "media", "raw"]], |
293 ); | 305 rules => rules.map(rule => rule.trigger["resource-type"]) |
294 | 306 ) |
295 test.done(); | 307 ]); |
296 }, | 308 }, |
297 | 309 |
298 testUnsupportedfilters: function(test) | 310 testUnsupportedfilters: function(test) |
299 { | 311 { |
300 // These types of filters are currently completely unsupported. | 312 runTest(test, [ |
301 testRules(test, ["foo$sitekey=bar"], []); | 313 // These types of filters are currently completely unsupported. |
302 | 314 testRules(test, ["foo$sitekey=bar"], []) |
303 test.done(); | 315 ]); |
304 }, | 316 }, |
305 | 317 |
306 testFilterOptions: function(test) | 318 testFilterOptions: function(test) |
307 { | 319 { |
308 testRules(test, ["1$domain=foo.com"], ["*foo.com"], | 320 runTest(test, [ |
309 rules => rules[0]["trigger"]["if-domain"]); | 321 testRules(test, ["1$domain=foo.com"], ["*foo.com"], |
310 testRules(test, ["2$third-party"], ["third-party"], | 322 rules => rules[0]["trigger"]["if-domain"]), |
311 rules => rules[0]["trigger"]["load-type"]); | 323 testRules(test, ["2$third-party"], ["third-party"], |
312 testRules(test, ["foo$match_case"], true, | 324 rules => rules[0]["trigger"]["load-type"]), |
313 rules => rules[0]["trigger"]["url-filter-is-case-sensitive"]); | 325 testRules(test, ["foo$match_case"], true, |
314 | 326 rules => rules[0]["trigger"]["url-filter-is-case-sensitive"]), |
315 // Test subdomain exceptions. | 327 |
316 testRules(test, ["1$domain=foo.com|~bar.foo.com"], | 328 // Test subdomain exceptions. |
317 ["foo.com", "www.foo.com"], | 329 testRules(test, ["1$domain=foo.com|~bar.foo.com"], |
318 rules => rules[0]["trigger"]["if-domain"]); | 330 ["foo.com", "www.foo.com"], |
319 testRules(test, ["1$domain=foo.com|~www.foo.com"], | 331 rules => rules[0]["trigger"]["if-domain"]), |
320 ["foo.com"], | 332 testRules(test, ["1$domain=foo.com|~www.foo.com"], |
321 rules => rules[0]["trigger"]["if-domain"]); | 333 ["foo.com"], |
322 | 334 rules => rules[0]["trigger"]["if-domain"]) |
323 test.done(); | 335 ]); |
324 }, | 336 }, |
325 | 337 |
326 testUnicode: function(test) | 338 testUnicode: function(test) |
327 { | 339 { |
328 testRules(test, ["$domain=🐈.cat"], ["*xn--zn8h.cat"], | 340 runTest(test, [ |
329 rules => rules[0]["trigger"]["if-domain"]); | 341 testRules(test, ["$domain=🐈.cat"], ["*xn--zn8h.cat"], |
330 testRules(test, ["||🐈"], "^[^:]+:(//)?([^/]+\\.)?xn--zn8h", | 342 rules => rules[0]["trigger"]["if-domain"]), |
331 rules => rules[0]["trigger"]["url-filter"]); | 343 testRules(test, ["||🐈"], "^[^:]+:(//)?([^/]+\\.)?xn--zn8h", |
332 testRules(test, ["🐈$domain=🐈.cat"], "^[^:]+:(//)?.*%F0%9F%90%88", | 344 rules => rules[0]["trigger"]["url-filter"]), |
333 rules => rules[0]["trigger"]["url-filter"]); | 345 testRules(test, ["🐈$domain=🐈.cat"], "^[^:]+:(//)?.*%F0%9F%90%88", |
334 testRules(test, ["🐈%F0%9F%90%88$domain=🐈.cat"], | 346 rules => rules[0]["trigger"]["url-filter"]), |
335 "^[^:]+:(//)?.*%F0%9F%90%88%F0%9F%90%88", | 347 testRules(test, ["🐈%F0%9F%90%88$domain=🐈.cat"], |
336 rules => rules[0]["trigger"]["url-filter"]); | 348 "^[^:]+:(//)?.*%F0%9F%90%88%F0%9F%90%88", |
337 testRules(test, ["###🐈"], "[id=🐈]", | 349 rules => rules[0]["trigger"]["url-filter"]), |
338 rules => rules[0]["action"]["selector"]); | 350 testRules(test, ["###🐈"], "[id=🐈]", |
339 | 351 rules => rules[0]["action"]["selector"]) |
340 test.done(); | 352 ]); |
341 }, | 353 }, |
342 | 354 |
343 testWebSocket: function(test) | 355 testWebSocket: function(test) |
344 { | 356 { |
345 testRules(test, ["foo$websocket"], [ | 357 runTest(test, [ |
346 {trigger: {"url-filter": "^wss?://.*foo", "resource-type": ["raw"]}, | 358 testRules(test, ["foo$websocket"], [ |
347 action: {type: "block"}} | 359 {trigger: {"url-filter": "^wss?://.*foo", "resource-type": ["raw"]}, |
348 ]); | 360 action: {type: "block"}} |
349 | 361 ]) |
350 test.done(); | 362 ]); |
351 }, | 363 }, |
352 | 364 |
353 testWebRTC: function(test) | 365 testWebRTC: function(test) |
354 { | 366 { |
355 testRules(test, ["foo$webrtc"], [ | 367 runTest(test, [ |
356 {trigger: {"url-filter": "^stuns?:.*foo", "resource-type": ["raw"]}, | 368 testRules(test, ["foo$webrtc"], [ |
357 action: {type: "block"}}, | 369 {trigger: {"url-filter": "^stuns?:.*foo", "resource-type": ["raw"]}, |
358 {trigger: {"url-filter": "^turns?:.*foo", "resource-type": ["raw"]}, | 370 action: {type: "block"}}, |
359 action: {type: "block"}} | 371 {trigger: {"url-filter": "^turns?:.*foo", "resource-type": ["raw"]}, |
360 ]); | 372 action: {type: "block"}} |
361 | 373 ]) |
362 test.done(); | 374 ]); |
| 375 }, |
| 376 |
| 377 testMerging: function(test) |
| 378 { |
| 379 runTest(test, [ |
| 380 // Single character substitutions, deletions, and insertions. |
| 381 testRules(test, ["/ads", "/adv"], ["^[^:]+:(//)?.*/ad[sv]"], |
| 382 rules => rules.map(rule => rule.trigger["url-filter"]), |
| 383 {merge: "all"}), |
| 384 testRules(test, ["/ads", "/advs"], ["^[^:]+:(//)?.*/adv?s"], |
| 385 rules => rules.map(rule => rule.trigger["url-filter"]), |
| 386 {merge: "all"}), |
| 387 testRules(test, ["/advs", "/ads"], ["^[^:]+:(//)?.*/adv?s"], |
| 388 rules => rules.map(rule => rule.trigger["url-filter"]), |
| 389 {merge: "all"}), |
| 390 testRules(test, ["/adts", "/advs", "/ads"], ["^[^:]+:(//)?.*/ad[tv]?s"], |
| 391 rules => rules.map(rule => rule.trigger["url-filter"]), |
| 392 {merge: "all"}), |
| 393 testRules(test, ["/ads", "/adts", "/advs"], ["^[^:]+:(//)?.*/ad[tv]?s"], |
| 394 rules => rules.map(rule => rule.trigger["url-filter"]), |
| 395 {merge: "all"}), |
| 396 testRules(test, ["/adts", "/ads", "/advs"], ["^[^:]+:(//)?.*/ad[tv]?s"], |
| 397 rules => rules.map(rule => rule.trigger["url-filter"]), |
| 398 {merge: "all"}), |
| 399 testRules(test, ["/ax", "/adx", "/adsx", "/advx"], |
| 400 ["^[^:]+:(//)?.*/ax", "^[^:]+:(//)?.*/ad[sv]?x"], |
| 401 rules => rules.map(rule => rule.trigger["url-filter"]), |
| 402 {merge: "all"}), |
| 403 testRules(test, ["/adx", "/ax", "/adsx", "/advx"], |
| 404 ["^[^:]+:(//)?.*/ax", "^[^:]+:(//)?.*/ad[sv]?x"], |
| 405 rules => rules.map(rule => rule.trigger["url-filter"]), |
| 406 {merge: "all"}), |
| 407 testRules(test, ["/adsx", "/advx", "/adx", "/ax"], |
| 408 ["^[^:]+:(//)?.*/ad[sv]?x", "^[^:]+:(//)?.*/ax"], |
| 409 rules => rules.map(rule => rule.trigger["url-filter"]), |
| 410 {merge: "all"}), |
| 411 testRules(test, ["/adsx", "/advx", "/ax", "/adx"], |
| 412 ["^[^:]+:(//)?.*/ad[sv]?x", "^[^:]+:(//)?.*/ax"], |
| 413 rules => rules.map(rule => rule.trigger["url-filter"]), |
| 414 {merge: "all"}), |
| 415 testRules(test, ["/ad-", "/a-", "/ads-", "/adv-", "/adx-"], |
| 416 ["^[^:]+:(//)?.*/a-", "^[^:]+:(//)?.*/ad[svx]?-"], |
| 417 rules => rules.map(rule => rule.trigger["url-filter"]), |
| 418 {merge: "all"}), |
| 419 testRules(test, ["/ads-", "/a-", "/ad-", "/adv-", "/adx-"], |
| 420 ["^[^:]+:(//)?.*/ad[svx]?-", "^[^:]+:(//)?.*/a-"], |
| 421 rules => rules.map(rule => rule.trigger["url-filter"]), |
| 422 {merge: "all"}), |
| 423 |
| 424 // Multiple character deletions and insertions. |
| 425 testRules(test, ["/ads", "/adxis"], |
| 426 ["^[^:]+:(//)?.*/ad(xi)?s"], |
| 427 rules => rules.map(rule => rule.trigger["url-filter"]), |
| 428 {merge: "all"}), |
| 429 testRules(test, ["/adxsi", "/xsi"], |
| 430 ["^[^:]+:(//)?.*/(ad)?xsi"], |
| 431 rules => rules.map(rule => rule.trigger["url-filter"]), |
| 432 {merge: "all"}), |
| 433 testRules(test, ["/adxsi", "/ai"], |
| 434 ["^[^:]+:(//)?.*/a(dxs)?i"], |
| 435 rules => rules.map(rule => rule.trigger["url-filter"]), |
| 436 {merge: "all"}), |
| 437 |
| 438 // Both single and multiple character edits combined. |
| 439 testRules(test, ["/adq", "/adxsiq", "/xsiq", "/axsiq", "/bxsiq"], |
| 440 ["^[^:]+:(//)?.*/ad(xsi)?q", "^[^:]+:(//)?.*/[ab]?xsiq"], |
| 441 rules => rules.map(rule => rule.trigger["url-filter"]), |
| 442 {merge: "all"}), |
| 443 |
| 444 testRules(test, ["/adsq", "/aq", "/adq", "/advq", "/adxq", "/adxsq"], |
| 445 ["^[^:]+:(//)?.*/ad[svx]?q", "^[^:]+:(//)?.*/a(dxs)?q"], |
| 446 rules => rules.map(rule => rule.trigger["url-filter"]), |
| 447 {merge: "all"}), |
| 448 testRules(test, ["/adxsq", "/aq", "/adq", "/adsq", "/advq", "/adxq"], |
| 449 ["^[^:]+:(//)?.*/a(dxs)?q", "^[^:]+:(//)?.*/ad[svx]?q"], |
| 450 rules => rules.map(rule => rule.trigger["url-filter"]), |
| 451 {merge: "all"}), |
| 452 testRules(test, ["/adxsq", "/aq", "/adsq", "/adq", "/advq", "/adxq"], |
| 453 ["^[^:]+:(//)?.*/a(dxs)?q", "^[^:]+:(//)?.*/ad[svx]?q"], |
| 454 rules => rules.map(rule => rule.trigger["url-filter"]), |
| 455 {merge: "all"}), |
| 456 testRules(test, ["/adxsq", "/aq", "/adsq", "/advq", "/adq", "/adxq"], |
| 457 ["^[^:]+:(//)?.*/a(dxs)?q", "^[^:]+:(//)?.*/ad[svx]?q"], |
| 458 rules => rules.map(rule => rule.trigger["url-filter"]), |
| 459 {merge: "all"}), |
| 460 testRules(test, ["/adsxiq", "/adxsq", "/aq", "/adsq", "/advq", "/adq", |
| 461 "/adxq"], |
| 462 ["^[^:]+:(//)?.*/a(dsxi)?q", "^[^:]+:(//)?.*/adxsq", |
| 463 "^[^:]+:(//)?.*/ad[svx]?q"], |
| 464 rules => rules.map(rule => rule.trigger["url-filter"]), |
| 465 {merge: "all"}), |
| 466 testRules(test, ["/adxsiq", "/adsxiq", "/adxsq", "/aq", "/adsq", "/advq", |
| 467 "/adq", "/adxq"], |
| 468 ["^[^:]+:(//)?.*/adxsi?q", "^[^:]+:(//)?.*/a(dsxi)?q", |
| 469 "^[^:]+:(//)?.*/ad[svx]?q"], |
| 470 rules => rules.map(rule => rule.trigger["url-filter"]), |
| 471 {merge: "all"}), |
| 472 |
| 473 // Given the 6 rules "adsi", "bdsi", "advi", "bdvi", "adxi", and "bdxi", |
| 474 // we want the 2 rules "ad[svx]i" and "bd[svx]i", not the 3 rules |
| 475 // "[ab]dsi", "[ab]dvi", and "[ab]dxi" |
| 476 testRules(test, ["/adsi", "/bdsi", "/advi", "/bdvi", "/adxi", "/bdxi"], |
| 477 ["^[^:]+:(//)?.*/ad[svx]i", "^[^:]+:(//)?.*/bd[svx]i"], |
| 478 rules => rules.map(rule => rule.trigger["url-filter"]), |
| 479 {merge: "all"}), |
| 480 testRules(test, ["/adsi", "/bdsi", "/advi", "/bdvi", "/bdxi"], |
| 481 ["^[^:]+:(//)?.*/ad[sv]i", "^[^:]+:(//)?.*/bd[svx]i"], |
| 482 rules => rules.map(rule => rule.trigger["url-filter"]), |
| 483 {merge: "all"}), |
| 484 |
| 485 // Make sure there's no merge where there are special characters in the |
| 486 // delta. |
| 487 testRules(test, ["/ads?q", "/adsq"], |
| 488 ["^[^:]+:(//)?.*/ads\\?q", "^[^:]+:(//)?.*/adsq"], |
| 489 rules => rules.map(rule => rule.trigger["url-filter"]), |
| 490 {merge: "all"}), |
| 491 testRules(test, ["/ads?", "/ads-"], |
| 492 ["^[^:]+:(//)?.*/ads\\?", "^[^:]+:(//)?.*/ads-"], |
| 493 rules => rules.map(rule => rule.trigger["url-filter"]), |
| 494 {merge: "all"}), |
| 495 testRules(test, ["/ads?-", "/ads-"], |
| 496 ["^[^:]+:(//)?.*/ads\\?-", "^[^:]+:(//)?.*/ads-"], |
| 497 rules => rules.map(rule => rule.trigger["url-filter"]), |
| 498 {merge: "all"}), |
| 499 |
| 500 // Redundant rules should be discarded. |
| 501 testRules(test, ["/ad", "/ads", "/advertisement"], |
| 502 ["^[^:]+:(//)?.*/ad"], |
| 503 rules => rules.map(rule => rule.trigger["url-filter"]), |
| 504 {merge: "all"}) |
| 505 ]); |
363 } | 506 } |
364 }; | 507 }; |
OLD | NEW |