Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code

Side by Side Diff: test/filterClasses.js

Issue 30025555: Issue 6820 - Move tests to mocha (Closed) Base URL: https://hg.adblockplus.org/adblockpluscore/
Patch Set: Rebased. Created April 5, 2019, 4:16 p.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff | Download patch
« no previous file with comments | « test/elemHide.js ('k') | test/filterListener.js » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 const {createSandbox} = require("./_common"); 21 const {createSandbox} = require("./_common");
21 22
22 let Filter = null; 23 let Filter = null;
23 let InvalidFilter = null; 24 let InvalidFilter = null;
24 let CommentFilter = null; 25 let CommentFilter = null;
25 let ActiveFilter = null; 26 let ActiveFilter = null;
26 let RegExpFilter = null; 27 let RegExpFilter = null;
27 let BlockingFilter = null; 28 let BlockingFilter = null;
28 let ContentFilter = null; 29 let ContentFilter = null;
29 let WhitelistFilter = null; 30 let WhitelistFilter = null;
30 let ElemHideBase = null; 31 let ElemHideBase = null;
31 let ElemHideFilter = null; 32 let ElemHideFilter = null;
32 let ElemHideException = null; 33 let ElemHideException = null;
33 let ElemHideEmulationFilter = null; 34 let ElemHideEmulationFilter = null;
34 let SnippetFilter = null; 35 let SnippetFilter = null;
35 36
36 let t = null; 37 let t = null;
37 let defaultTypes = null; 38 let defaultTypes = null;
38 39
39 exports.setUp = function(callback) 40 describe("Filters Classes", () =>
40 { 41 {
41 let sandboxedRequire = createSandbox(); 42 beforeEach(() =>
42 ( 43 {
43 {Filter, InvalidFilter, CommentFilter, ActiveFilter, RegExpFilter, 44 let sandboxedRequire = createSandbox();
44 BlockingFilter, WhitelistFilter, ContentFilter, ElemHideBase, 45 (
45 ElemHideFilter, ElemHideException, ElemHideEmulationFilter, 46 {Filter, InvalidFilter, CommentFilter, ActiveFilter, RegExpFilter,
46 SnippetFilter} = sandboxedRequire("../lib/filterClasses") 47 BlockingFilter, WhitelistFilter, ContentFilter, ElemHideBase,
47 ); 48 ElemHideFilter, ElemHideException, ElemHideEmulationFilter,
48 t = RegExpFilter.typeMap; 49 SnippetFilter} = sandboxedRequire("../lib/filterClasses")
49 defaultTypes = 0x7FFFFFFF & ~(t.CSP | t.ELEMHIDE | t.DOCUMENT | t.POPUP | 50 );
50 t.GENERICHIDE | t.GENERICBLOCK); 51 t = RegExpFilter.typeMap;
51 52 defaultTypes = 0x7FFFFFFF & ~(t.CSP | t.ELEMHIDE | t.DOCUMENT | t.POPUP |
52 callback(); 53 t.GENERICHIDE | t.GENERICBLOCK);
53 }; 54 });
54 55
55 function serializeFilter(filter) 56 function serializeFilter(filter)
56 { 57 {
57 // Filter serialization only writes out essential properties, need to do a ful l serialization here 58 // Filter serialization only writes out essential properties, need to do a f ull serialization here
58 let result = []; 59 let result = [];
59 result.push("text=" + filter.text); 60 result.push("text=" + filter.text);
60 if (filter instanceof InvalidFilter) 61 if (filter instanceof InvalidFilter)
61 { 62 {
62 result.push("type=invalid"); 63 result.push("type=invalid");
63 result.push("reason=" + filter.reason); 64 result.push("reason=" + filter.reason);
65 }
66 else if (filter instanceof CommentFilter)
67 result.push("type=comment");
68 else if (filter instanceof ActiveFilter)
69 {
70 result.push("disabled=" + filter.disabled);
71 result.push("lastHit=" + filter.lastHit);
72 result.push("hitCount=" + filter.hitCount);
73
74 let domains = [];
75 if (filter.domains)
76 {
77 for (let [domain, isIncluded] of filter.domains)
78 {
79 if (domain != "")
80 domains.push(isIncluded ? domain : "~" + domain);
81 }
82 }
83 result.push("domains=" + domains.sort().join("|"));
84
85 if (filter instanceof RegExpFilter)
86 {
87 result.push("regexp=" + (filter.regexp ? filter.regexp.source : null));
88 result.push("contentType=" + filter.contentType);
89 result.push("matchCase=" + filter.matchCase);
90
91 let sitekeys = filter.sitekeys || [];
92 result.push("sitekeys=" + sitekeys.slice().sort().join("|"));
93
94 result.push("thirdParty=" + filter.thirdParty);
95 if (filter instanceof BlockingFilter)
96 {
97 result.push("type=filterlist");
98 result.push("collapse=" + filter.collapse);
99 result.push("csp=" + filter.csp);
100 result.push("rewrite=" + filter.rewrite);
101 }
102 else if (filter instanceof WhitelistFilter)
103 result.push("type=whitelist");
104 }
105 else if (filter instanceof ElemHideBase)
106 {
107 if (filter instanceof ElemHideFilter)
108 result.push("type=elemhide");
109 else if (filter instanceof ElemHideException)
110 result.push("type=elemhideexception");
111 else if (filter instanceof ElemHideEmulationFilter)
112 result.push("type=elemhideemulation");
113
114 result.push("selectorDomains=" +
115 [...filter.domains || []]
116 .filter(([domain, isIncluded]) => isIncluded)
117 .map(([domain]) => domain.toLowerCase()));
118 result.push("selector=" + filter.selector);
119 }
120 else if (filter instanceof SnippetFilter)
121 {
122 result.push("type=snippet");
123 result.push("scriptDomains=" +
124 [...filter.domains || []]
125 .filter(([domain, isIncluded]) => isIncluded)
126 .map(([domain]) => domain.toLowerCase()));
127 result.push("script=" + filter.script);
128 }
129 }
130 return result;
64 } 131 }
65 else if (filter instanceof CommentFilter) 132
66 result.push("type=comment"); 133 function addDefaults(expected)
67 else if (filter instanceof ActiveFilter) 134 {
68 { 135 let type = null;
69 result.push("disabled=" + filter.disabled); 136 let hasProperty = {};
70 result.push("lastHit=" + filter.lastHit); 137 for (let entry of expected)
71 result.push("hitCount=" + filter.hitCount); 138 {
72 139 if (/^type=(.*)/.test(entry))
73 let domains = []; 140 type = RegExp.$1;
74 if (filter.domains) 141 else if (/^(\w+)/.test(entry))
75 { 142 hasProperty[RegExp.$1] = true;
76 for (let [domain, isIncluded] of filter.domains) 143 }
77 { 144
78 if (domain != "") 145 function addProperty(prop, value)
79 domains.push(isIncluded ? domain : "~" + domain); 146 {
80 } 147 if (!(prop in hasProperty))
81 } 148 expected.push(prop + "=" + value);
82 result.push("domains=" + domains.sort().join("|")); 149 }
83 150
84 if (filter instanceof RegExpFilter) 151 if (type == "whitelist" || type == "filterlist" || type == "elemhide" ||
85 { 152 type == "elemhideexception" || type == "elemhideemulation" ||
86 result.push("regexp=" + (filter.regexp ? filter.regexp.source : null)); 153 type == "snippet")
87 result.push("contentType=" + filter.contentType); 154 {
88 result.push("matchCase=" + filter.matchCase); 155 addProperty("disabled", "false");
89 156 addProperty("lastHit", "0");
90 let sitekeys = filter.sitekeys || []; 157 addProperty("hitCount", "0");
91 result.push("sitekeys=" + sitekeys.slice().sort().join("|")); 158 }
92 159 if (type == "whitelist" || type == "filterlist")
93 result.push("thirdParty=" + filter.thirdParty); 160 {
94 if (filter instanceof BlockingFilter) 161 addProperty("contentType", 0x7FFFFFFF & ~(
95 { 162 t.CSP | t.DOCUMENT | t.ELEMHIDE | t.POPUP | t.GENERICHIDE | t.GENERICBLO CK
96 result.push("type=filterlist"); 163 ));
97 result.push("collapse=" + filter.collapse); 164 addProperty("regexp", "null");
98 result.push("csp=" + filter.csp); 165 addProperty("matchCase", "false");
99 result.push("rewrite=" + filter.rewrite); 166 addProperty("thirdParty", "null");
100 } 167 addProperty("domains", "");
101 else if (filter instanceof WhitelistFilter) 168 addProperty("sitekeys", "");
102 result.push("type=whitelist"); 169 }
103 } 170 if (type == "filterlist")
104 else if (filter instanceof ElemHideBase) 171 {
105 { 172 addProperty("collapse", "null");
106 if (filter instanceof ElemHideFilter) 173 addProperty("csp", "null");
107 result.push("type=elemhide"); 174 addProperty("rewrite", "null");
108 else if (filter instanceof ElemHideException) 175 }
109 result.push("type=elemhideexception"); 176 if (type == "elemhide" || type == "elemhideexception" ||
110 else if (filter instanceof ElemHideEmulationFilter) 177 type == "elemhideemulation")
111 result.push("type=elemhideemulation"); 178 {
112 179 addProperty("selectorDomains", "");
113 result.push("selectorDomains=" + 180 addProperty("domains", "");
114 [...filter.domains || []] 181 }
115 .filter(([domain, isIncluded]) => isIncluded) 182 if (type == "snippet")
116 .map(([domain]) => domain.toLowerCase())); 183 {
117 result.push("selector=" + filter.selector); 184 addProperty("scriptDomains", "");
118 } 185 addProperty("domains", "");
119 else if (filter instanceof SnippetFilter)
120 {
121 result.push("type=snippet");
122 result.push("scriptDomains=" +
123 [...filter.domains || []]
124 .filter(([domain, isIncluded]) => isIncluded)
125 .map(([domain]) => domain.toLowerCase()));
126 result.push("script=" + filter.script);
127 } 186 }
128 } 187 }
129 return result; 188
130 } 189 function compareFilter(text, expected, postInit)
131 190 {
132 function addDefaults(expected) 191 addDefaults(expected);
133 { 192
134 let type = null; 193 let filter = Filter.fromText(text);
135 let hasProperty = {}; 194 if (postInit)
136 for (let entry of expected) 195 postInit(filter);
137 { 196 let result = serializeFilter(filter);
138 if (/^type=(.*)/.test(entry)) 197 assert.equal(result.sort().join("\n"), expected.sort().join("\n"), text);
139 type = RegExp.$1; 198
140 else if (/^(\w+)/.test(entry)) 199 // Test round-trip
141 hasProperty[RegExp.$1] = true; 200 let filter2;
201 let buffer = [...filter.serialize()];
202 if (buffer.length)
203 {
204 let map = Object.create(null);
205 for (let line of buffer.slice(1))
206 {
207 if (/(.*?)=(.*)/.test(line))
208 map[RegExp.$1] = RegExp.$2;
209 }
210 filter2 = Filter.fromObject(map);
211 }
212 else
213 filter2 = Filter.fromText(filter.text);
214
215 assert.equal(serializeFilter(filter).join("\n"), serializeFilter(filter2).jo in("\n"), text + " deserialization");
142 } 216 }
143 217
144 function addProperty(prop, value) 218 it("Definitions", () =>
145 { 219 {
146 if (!(prop in hasProperty)) 220 assert.equal(typeof Filter, "function", "typeof Filter");
147 expected.push(prop + "=" + value); 221 assert.equal(typeof InvalidFilter, "function", "typeof InvalidFilter");
148 } 222 assert.equal(typeof CommentFilter, "function", "typeof CommentFilter");
149 223 assert.equal(typeof ActiveFilter, "function", "typeof ActiveFilter");
150 if (type == "whitelist" || type == "filterlist" || type == "elemhide" || 224 assert.equal(typeof RegExpFilter, "function", "typeof RegExpFilter");
151 type == "elemhideexception" || type == "elemhideemulation" || 225 assert.equal(typeof BlockingFilter, "function", "typeof BlockingFilter");
152 type == "snippet") 226 assert.equal(typeof ContentFilter, "function", "typeof ContentFilter");
153 { 227 assert.equal(typeof WhitelistFilter, "function", "typeof WhitelistFilter");
154 addProperty("disabled", "false"); 228 assert.equal(typeof ElemHideBase, "function", "typeof ElemHideBase");
155 addProperty("lastHit", "0"); 229 assert.equal(typeof ElemHideFilter, "function", "typeof ElemHideFilter");
156 addProperty("hitCount", "0"); 230 assert.equal(typeof ElemHideException,
157 } 231 "function", "typeof ElemHideException");
158 if (type == "whitelist" || type == "filterlist") 232 assert.equal(typeof ElemHideEmulationFilter, "function",
159 { 233 "typeof ElemHideEmulationFilter");
160 addProperty("contentType", 0x7FFFFFFF & ~( 234 assert.equal(typeof SnippetFilter, "function", "typeof SnippetFilter");
161 t.CSP | t.DOCUMENT | t.ELEMHIDE | t.POPUP | t.GENERICHIDE | t.GENERICBLOCK 235 });
162 )); 236
163 addProperty("regexp", "null"); 237 it("Comments", () =>
164 addProperty("matchCase", "false"); 238 {
165 addProperty("thirdParty", "null"); 239 compareFilter("!asdf", ["type=comment", "text=!asdf"]);
166 addProperty("domains", ""); 240 compareFilter("!foo#bar", ["type=comment", "text=!foo#bar"]);
167 addProperty("sitekeys", ""); 241 compareFilter("!foo##bar", ["type=comment", "text=!foo##bar"]);
168 } 242 });
169 if (type == "filterlist") 243
170 { 244 it("Invalid Filters", () =>
171 addProperty("collapse", "null"); 245 {
172 addProperty("csp", "null"); 246 compareFilter("/??/", ["type=invalid", "text=/??/", "reason=filter_invalid_r egexp"]);
173 addProperty("rewrite", "null"); 247 compareFilter("asd$foobar", ["type=invalid", "text=asd$foobar", "reason=filt er_unknown_option"]);
174 } 248
175 if (type == "elemhide" || type == "elemhideexception" || 249 // No $domain or $~third-party
176 type == "elemhideemulation") 250 compareFilter("||example.com/ad.js$rewrite=abp-resource:noopjs", ["type=inva lid", "text=||example.com/ad.js$rewrite=abp-resource:noopjs", "reason=filter_inv alid_rewrite"]);
177 { 251 compareFilter("*example.com/ad.js$rewrite=abp-resource:noopjs", ["type=inval id", "text=*example.com/ad.js$rewrite=abp-resource:noopjs", "reason=filter_inval id_rewrite"]);
178 addProperty("selectorDomains", ""); 252 compareFilter("example.com/ad.js$rewrite=abp-resource:noopjs", ["type=invali d", "text=example.com/ad.js$rewrite=abp-resource:noopjs", "reason=filter_invalid _rewrite"]);
179 addProperty("domains", ""); 253 // Patterns not starting with || or *
180 } 254 compareFilter("example.com/ad.js$rewrite=abp-resource:noopjs,domain=foo.com" , ["type=invalid", "text=example.com/ad.js$rewrite=abp-resource:noopjs,domain=fo o.com", "reason=filter_invalid_rewrite"]);
181 if (type == "snippet") 255 compareFilter("example.com/ad.js$rewrite=abp-resource:noopjs,~third-party", ["type=invalid", "text=example.com/ad.js$rewrite=abp-resource:noopjs,~third-part y", "reason=filter_invalid_rewrite"]);
182 { 256 // $~third-party requires ||
183 addProperty("scriptDomains", ""); 257 compareFilter("*example.com/ad.js$rewrite=abp-resource:noopjs,~third-party", ["type=invalid", "text=*example.com/ad.js$rewrite=abp-resource:noopjs,~third-pa rty", "reason=filter_invalid_rewrite"]);
184 addProperty("domains", ""); 258
185 } 259 function checkElemHideEmulationFilterInvalid(domains)
186 } 260 {
187 261 let filterText = domains + "#?#:-abp-properties(abc)";
188 function compareFilter(test, text, expected, postInit) 262 compareFilter(
189 { 263 filterText, [
190 addDefaults(expected); 264 "type=invalid", "text=" + filterText,
191 265 "reason=filter_elemhideemulation_nodomain"
192 let filter = Filter.fromText(text); 266 ]
193 if (postInit) 267 );
194 postInit(filter); 268 }
195 let result = serializeFilter(filter); 269 checkElemHideEmulationFilterInvalid("");
196 test.equal(result.sort().join("\n"), expected.sort().join("\n"), text); 270 checkElemHideEmulationFilterInvalid("~foo.com");
197 271 checkElemHideEmulationFilterInvalid("~foo.com,~bar.com");
198 // Test round-trip 272 checkElemHideEmulationFilterInvalid("foo");
199 let filter2; 273 checkElemHideEmulationFilterInvalid("~foo.com,bar");
200 let buffer = [...filter.serialize()]; 274 });
201 if (buffer.length) 275
202 { 276 it("Filters with State", () =>
203 let map = Object.create(null); 277 {
204 for (let line of buffer.slice(1)) 278 compareFilter("blabla", ["type=filterlist", "text=blabla"]);
205 {
206 if (/(.*?)=(.*)/.test(line))
207 map[RegExp.$1] = RegExp.$2;
208 }
209 filter2 = Filter.fromObject(map);
210 }
211 else
212 filter2 = Filter.fromText(filter.text);
213
214 test.equal(serializeFilter(filter).join("\n"), serializeFilter(filter2).join(" \n"), text + " deserialization");
215 }
216
217 exports.testFilterClassDefinitions = function(test)
218 {
219 test.equal(typeof Filter, "function", "typeof Filter");
220 test.equal(typeof InvalidFilter, "function", "typeof InvalidFilter");
221 test.equal(typeof CommentFilter, "function", "typeof CommentFilter");
222 test.equal(typeof ActiveFilter, "function", "typeof ActiveFilter");
223 test.equal(typeof RegExpFilter, "function", "typeof RegExpFilter");
224 test.equal(typeof BlockingFilter, "function", "typeof BlockingFilter");
225 test.equal(typeof ContentFilter, "function", "typeof ContentFilter");
226 test.equal(typeof WhitelistFilter, "function", "typeof WhitelistFilter");
227 test.equal(typeof ElemHideBase, "function", "typeof ElemHideBase");
228 test.equal(typeof ElemHideFilter, "function", "typeof ElemHideFilter");
229 test.equal(typeof ElemHideException, "function", "typeof ElemHideException");
230 test.equal(typeof ElemHideEmulationFilter, "function",
231 "typeof ElemHideEmulationFilter");
232 test.equal(typeof SnippetFilter, "function", "typeof SnippetFilter");
233
234 test.done();
235 };
236
237 exports.testComments = function(test)
238 {
239 compareFilter(test, "!asdf", ["type=comment", "text=!asdf"]);
240 compareFilter(test, "!foo#bar", ["type=comment", "text=!foo#bar"]);
241 compareFilter(test, "!foo##bar", ["type=comment", "text=!foo##bar"]);
242
243 test.done();
244 };
245
246 exports.testInvalidFilters = function(test)
247 {
248 compareFilter(test, "/??/", ["type=invalid", "text=/??/", "reason=filter_inval id_regexp"]);
249 compareFilter(test, "asd$foobar", ["type=invalid", "text=asd$foobar", "reason= filter_unknown_option"]);
250
251 // No $domain or $~third-party
252 compareFilter(test, "||example.com/ad.js$rewrite=abp-resource:noopjs", ["type= invalid", "text=||example.com/ad.js$rewrite=abp-resource:noopjs", "reason=filter _invalid_rewrite"]);
253 compareFilter(test, "*example.com/ad.js$rewrite=abp-resource:noopjs", ["type=i nvalid", "text=*example.com/ad.js$rewrite=abp-resource:noopjs", "reason=filter_i nvalid_rewrite"]);
254 compareFilter(test, "example.com/ad.js$rewrite=abp-resource:noopjs", ["type=in valid", "text=example.com/ad.js$rewrite=abp-resource:noopjs", "reason=filter_inv alid_rewrite"]);
255 // Patterns not starting with || or *
256 compareFilter(test, "example.com/ad.js$rewrite=abp-resource:noopjs,domain=foo. com", ["type=invalid", "text=example.com/ad.js$rewrite=abp-resource:noopjs,domai n=foo.com", "reason=filter_invalid_rewrite"]);
257 compareFilter(test, "example.com/ad.js$rewrite=abp-resource:noopjs,~third-part y", ["type=invalid", "text=example.com/ad.js$rewrite=abp-resource:noopjs,~third- party", "reason=filter_invalid_rewrite"]);
258 // $~third-party requires ||
259 compareFilter(test, "*example.com/ad.js$rewrite=abp-resource:noopjs,~third-par ty", ["type=invalid", "text=*example.com/ad.js$rewrite=abp-resource:noopjs,~thir d-party", "reason=filter_invalid_rewrite"]);
260
261 function checkElemHideEmulationFilterInvalid(domains)
262 {
263 let filterText = domains + "#?#:-abp-properties(abc)";
264 compareFilter( 279 compareFilter(
265 test, filterText, [ 280 "blabla_default", ["type=filterlist", "text=blabla_default"],
266 "type=invalid", "text=" + filterText, 281 filter =>
267 "reason=filter_elemhideemulation_nodomain" 282 {
283 filter.disabled = false;
284 filter.hitCount = 0;
285 filter.lastHit = 0;
286 }
287 );
288 compareFilter(
289 "blabla_non_default",
290 ["type=filterlist", "text=blabla_non_default", "disabled=true", "hitCount= 12", "lastHit=20"],
291 filter =>
292 {
293 filter.disabled = true;
294 filter.hitCount = 12;
295 filter.lastHit = 20;
296 }
297 );
298 });
299
300 it("Special Characters", () =>
301 {
302 compareFilter("/ddd|f?a[s]d/", ["type=filterlist", "text=/ddd|f?a[s]d/", "re gexp=ddd|f?a[s]d"]);
303 compareFilter("*asdf*d**dd*", ["type=filterlist", "text=*asdf*d**dd*", "rege xp=asdf.*d.*dd"]);
304 compareFilter("|*asd|f*d**dd*|", ["type=filterlist", "text=|*asd|f*d**dd*|", "regexp=^.*asd\\|f.*d.*dd.*$"]);
305 compareFilter("dd[]{}$%<>&()*d", ["type=filterlist", "text=dd[]{}$%<>&()*d", "regexp=dd\\[\\]\\{\\}\\$\\%\\<\\>\\&\\(\\).*d"]);
306
307 // Leading and trailing wildcards should be left in for rewrite filters (#68 68).
308 compareFilter("*asdf*d**dd*$rewrite=", ["type=filterlist", "text=*asdf*d**dd *$rewrite=", "regexp=.*asdf.*d.*dd.*", "rewrite=", "contentType=" + (defaultType s & ~(t.SCRIPT | t.SUBDOCUMENT | t.OBJECT | t.OBJECT_SUBREQUEST))]);
309
310 compareFilter("@@/ddd|f?a[s]d/", ["type=whitelist", "text=@@/ddd|f?a[s]d/", "regexp=ddd|f?a[s]d", "contentType=" + defaultTypes]);
311 compareFilter("@@*asdf*d**dd*", ["type=whitelist", "text=@@*asdf*d**dd*", "r egexp=asdf.*d.*dd", "contentType=" + defaultTypes]);
312 compareFilter("@@|*asd|f*d**dd*|", ["type=whitelist", "text=@@|*asd|f*d**dd* |", "regexp=^.*asd\\|f.*d.*dd.*$", "contentType=" + defaultTypes]);
313 compareFilter("@@dd[]{}$%<>&()*d", ["type=whitelist", "text=@@dd[]{}$%<>&()* d", "regexp=dd\\[\\]\\{\\}\\$\\%\\<\\>\\&\\(\\).*d", "contentType=" + defaultTyp es]);
314 });
315
316 it("Filter Options", () =>
317 {
318 compareFilter("bla$match-case,csp=first csp,script,other,third-party,domain= FOO.cOm,sitekey=foo", ["type=filterlist", "text=bla$match-case,csp=first csp,scr ipt,other,third-party,domain=FOO.cOm,sitekey=foo", "matchCase=true", "contentTyp e=" + (t.SCRIPT | t.OTHER | t.CSP), "thirdParty=true", "domains=foo.com", "sitek eys=FOO", "csp=first csp"]);
319 compareFilter("bla$~match-case,~csp=csp,~script,~other,~third-party,domain=~ bAr.coM", ["type=filterlist", "text=bla$~match-case,~csp=csp,~script,~other,~thi rd-party,domain=~bAr.coM", "contentType=" + (defaultTypes & ~(t.SCRIPT | t.OTHER )), "thirdParty=false", "domains=~bar.com"]);
320 compareFilter("@@bla$match-case,script,other,third-party,domain=foo.com|bar. com|~bAR.foO.Com|~Foo.Bar.com,csp=c s p,sitekey=foo|bar", ["type=whitelist", "te xt=@@bla$match-case,script,other,third-party,domain=foo.com|bar.com|~bAR.foO.Com |~Foo.Bar.com,csp=c s p,sitekey=foo|bar", "matchCase=true", "contentType=" + (t. SCRIPT | t.OTHER | t.CSP), "thirdParty=true", "domains=bar.com|foo.com|~bar.foo. com|~foo.bar.com", "sitekeys=BAR|FOO"]);
321 compareFilter("@@bla$match-case,script,other,third-party,domain=foo.com|bar. com|~bar.foo.com|~foo.bar.com,sitekey=foo|bar", ["type=whitelist", "text=@@bla$m atch-case,script,other,third-party,domain=foo.com|bar.com|~bar.foo.com|~foo.bar. com,sitekey=foo|bar", "matchCase=true", "contentType=" + (t.SCRIPT | t.OTHER), " thirdParty=true", "domains=bar.com|foo.com|~bar.foo.com|~foo.bar.com", "sitekeys =BAR|FOO"]);
322 compareFilter("||content.server.com/files/*.php$rewrite=$1", ["type=filterli st", "text=||content.server.com/files/*.php$rewrite=$1", "regexp=^[\\w\\-]+:\\/+ (?!\\/)(?:[^\\/]+\\.)?content\\.server\\.com\\/files\\/.*\\.php", "matchCase=fal se", "rewrite=$1", "contentType=" + (defaultTypes & ~(t.SCRIPT | t.SUBDOCUMENT | t.OBJECT | t.OBJECT_SUBREQUEST))]);
323
324 compareFilter("||example.com/ad.js$rewrite=abp-resource:noopjs,domain=foo.co m|bar.com", ["type=filterlist", "text=||example.com/ad.js$rewrite=abp-resource:n oopjs,domain=foo.com|bar.com", "regexp=null", "matchCase=false", "rewrite=abp-re source:noopjs", "contentType=" + (defaultTypes), "domains=bar.com|foo.com"]);
325 compareFilter("*example.com/ad.js$rewrite=abp-resource:noopjs,domain=foo.com |bar.com", ["type=filterlist", "text=*example.com/ad.js$rewrite=abp-resource:noo pjs,domain=foo.com|bar.com", "regexp=null", "matchCase=false", "rewrite=abp-reso urce:noopjs", "contentType=" + (defaultTypes), "domains=bar.com|foo.com"]);
326 compareFilter("||example.com/ad.js$rewrite=abp-resource:noopjs,~third-party" , ["type=filterlist", "text=||example.com/ad.js$rewrite=abp-resource:noopjs,~thi rd-party", "regexp=null", "matchCase=false", "rewrite=abp-resource:noopjs", "thi rdParty=false", "contentType=" + (defaultTypes)]);
327
328 // background and image should be the same for backwards compatibility
329 compareFilter("bla$image", ["type=filterlist", "text=bla$image", "contentTyp e=" + (t.IMAGE)]);
330 compareFilter("bla$background", ["type=filterlist", "text=bla$background", " contentType=" + (t.IMAGE)]);
331 compareFilter("bla$~image", ["type=filterlist", "text=bla$~image", "contentT ype=" + (defaultTypes & ~t.IMAGE)]);
332 compareFilter("bla$~background", ["type=filterlist", "text=bla$~background", "contentType=" + (defaultTypes & ~t.IMAGE)]);
333
334 compareFilter("@@bla$~script,~other", ["type=whitelist", "text=@@bla$~script ,~other", "contentType=" + (defaultTypes & ~(t.SCRIPT | t.OTHER))]);
335 compareFilter("@@http://bla$~script,~other", ["type=whitelist", "text=@@http ://bla$~script,~other", "contentType=" + (defaultTypes & ~(t.SCRIPT | t.OTHER))] );
336 compareFilter("@@|ftp://bla$~script,~other", ["type=whitelist", "text=@@|ftp ://bla$~script,~other", "regexp=^ftp\\:\\/\\/bla", "contentType=" + (defaultType s & ~(t.SCRIPT | t.OTHER))]);
337 compareFilter("@@bla$~script,~other,document", ["type=whitelist", "text=@@bl a$~script,~other,document", "contentType=" + (defaultTypes & ~(t.SCRIPT | t.OTHE R) | t.DOCUMENT)]);
338 compareFilter("@@bla$~script,~other,~document", ["type=whitelist", "text=@@b la$~script,~other,~document", "contentType=" + (defaultTypes & ~(t.SCRIPT | t.OT HER))]);
339 compareFilter("@@bla$document", ["type=whitelist", "text=@@bla$document", "c ontentType=" + t.DOCUMENT]);
340 compareFilter("@@bla$~script,~other,elemhide", ["type=whitelist", "text=@@bl a$~script,~other,elemhide", "contentType=" + (defaultTypes & ~(t.SCRIPT | t.OTHE R) | t.ELEMHIDE)]);
341 compareFilter("@@bla$~script,~other,~elemhide", ["type=whitelist", "text=@@b la$~script,~other,~elemhide", "contentType=" + (defaultTypes & ~(t.SCRIPT | t.OT HER))]);
342 compareFilter("@@bla$elemhide", ["type=whitelist", "text=@@bla$elemhide", "c ontentType=" + t.ELEMHIDE]);
343
344 compareFilter("@@bla$~script,~other,donottrack", ["type=invalid", "text=@@bl a$~script,~other,donottrack", "reason=filter_unknown_option"]);
345 compareFilter("@@bla$~script,~other,~donottrack", ["type=invalid", "text=@@b la$~script,~other,~donottrack", "reason=filter_unknown_option"]);
346 compareFilter("@@bla$donottrack", ["type=invalid", "text=@@bla$donottrack", "reason=filter_unknown_option"]);
347 compareFilter("@@bla$foobar", ["type=invalid", "text=@@bla$foobar", "reason= filter_unknown_option"]);
348 compareFilter("@@bla$image,foobar", ["type=invalid", "text=@@bla$image,fooba r", "reason=filter_unknown_option"]);
349 compareFilter("@@bla$foobar,image", ["type=invalid", "text=@@bla$foobar,imag e", "reason=filter_unknown_option"]);
350
351 compareFilter("bla$csp", ["type=invalid", "text=bla$csp", "reason=filter_inv alid_csp"]);
352 compareFilter("bla$csp=", ["type=invalid", "text=bla$csp=", "reason=filter_i nvalid_csp"]);
353
354 // Blank CSP values are allowed for whitelist filters.
355 compareFilter("@@bla$csp", ["type=whitelist", "text=@@bla$csp", "contentType =" + t.CSP]);
356 compareFilter("@@bla$csp=", ["type=whitelist", "text=@@bla$csp=", "contentTy pe=" + t.CSP]);
357
358 compareFilter("bla$csp=report-uri", ["type=invalid", "text=bla$csp=report-ur i", "reason=filter_invalid_csp"]);
359 compareFilter("bla$csp=foo,csp=report-to", ["type=invalid", "text=bla$csp=fo o,csp=report-to", "reason=filter_invalid_csp"]);
360 compareFilter("bla$csp=foo,csp=referrer foo", ["type=invalid", "text=bla$csp =foo,csp=referrer foo", "reason=filter_invalid_csp"]);
361 compareFilter("bla$csp=foo,csp=base-uri", ["type=invalid", "text=bla$csp=foo ,csp=base-uri", "reason=filter_invalid_csp"]);
362 compareFilter("bla$csp=foo,csp=upgrade-insecure-requests", ["type=invalid", "text=bla$csp=foo,csp=upgrade-insecure-requests", "reason=filter_invalid_csp"]);
363 compareFilter("bla$csp=foo,csp=ReFeRReR", ["type=invalid", "text=bla$csp=foo ,csp=ReFeRReR", "reason=filter_invalid_csp"]);
364 });
365
366 it("Element Hiding Rules", () =>
367 {
368 compareFilter("##ddd", ["type=elemhide", "text=##ddd", "selector=ddd"]);
369 compareFilter("##body > div:first-child", ["type=elemhide", "text=##body > d iv:first-child", "selector=body > div:first-child"]);
370 compareFilter("fOO##ddd", ["type=elemhide", "text=fOO##ddd", "selectorDomain s=foo", "selector=ddd", "domains=foo"]);
371 compareFilter("Foo,bAr##ddd", ["type=elemhide", "text=Foo,bAr##ddd", "select orDomains=foo,bar", "selector=ddd", "domains=bar|foo"]);
372 compareFilter("foo,~baR##ddd", ["type=elemhide", "text=foo,~baR##ddd", "sele ctorDomains=foo", "selector=ddd", "domains=foo|~bar"]);
373 compareFilter("foo,~baz,bar##ddd", ["type=elemhide", "text=foo,~baz,bar##ddd ", "selectorDomains=foo,bar", "selector=ddd", "domains=bar|foo|~baz"]);
374 });
375
376 it("Element Hiding Exceptions", () =>
377 {
378 compareFilter("#@#ddd", ["type=elemhideexception", "text=#@#ddd", "selector= ddd"]);
379 compareFilter("#@#body > div:first-child", ["type=elemhideexception", "text= #@#body > div:first-child", "selector=body > div:first-child"]);
380 compareFilter("fOO#@#ddd", ["type=elemhideexception", "text=fOO#@#ddd", "sel ectorDomains=foo", "selector=ddd", "domains=foo"]);
381 compareFilter("Foo,bAr#@#ddd", ["type=elemhideexception", "text=Foo,bAr#@#dd d", "selectorDomains=foo,bar", "selector=ddd", "domains=bar|foo"]);
382 compareFilter("foo,~baR#@#ddd", ["type=elemhideexception", "text=foo,~baR#@# ddd", "selectorDomains=foo", "selector=ddd", "domains=foo|~bar"]);
383 compareFilter("foo,~baz,bar#@#ddd", ["type=elemhideexception", "text=foo,~ba z,bar#@#ddd", "selectorDomains=foo,bar", "selector=ddd", "domains=bar|foo|~baz"] );
384 });
385
386 it("Element Hiding Emulation Filters", () =>
387 {
388 // Check valid domain combinations
389 compareFilter("fOO.cOm#?#:-abp-properties(abc)", ["type=elemhideemulation", "text=fOO.cOm#?#:-abp-properties(abc)", "selectorDomains=foo.com", "selector=:-a bp-properties(abc)", "domains=foo.com"]);
390 compareFilter("Foo.com,~bAr.com#?#:-abp-properties(abc)", ["type=elemhideemu lation", "text=Foo.com,~bAr.com#?#:-abp-properties(abc)", "selectorDomains=foo.c om", "selector=:-abp-properties(abc)", "domains=foo.com|~bar.com"]);
391 compareFilter("foo.com,~baR#?#:-abp-properties(abc)", ["type=elemhideemulati on", "text=foo.com,~baR#?#:-abp-properties(abc)", "selectorDomains=foo.com", "se lector=:-abp-properties(abc)", "domains=foo.com|~bar"]);
392 compareFilter("~foo.com,bar.com#?#:-abp-properties(abc)", ["type=elemhideemu lation", "text=~foo.com,bar.com#?#:-abp-properties(abc)", "selectorDomains=bar.c om", "selector=:-abp-properties(abc)", "domains=bar.com|~foo.com"]);
393
394 // Check some special cases
395 compareFilter("#?#:-abp-properties(abc)", ["type=invalid", "text=#?#:-abp-pr operties(abc)", "reason=filter_elemhideemulation_nodomain"]);
396 compareFilter("foo.com#?#abc", ["type=elemhideemulation", "text=foo.com#?#ab c", "selectorDomains=foo.com", "selector=abc", "domains=foo.com"]);
397 compareFilter("foo.com#?#:-abp-foobar(abc)", ["type=elemhideemulation", "tex t=foo.com#?#:-abp-foobar(abc)", "selectorDomains=foo.com", "selector=:-abp-fooba r(abc)", "domains=foo.com"]);
398 compareFilter("foo.com#?#aaa :-abp-properties(abc) bbb", ["type=elemhideemul ation", "text=foo.com#?#aaa :-abp-properties(abc) bbb", "selectorDomains=foo.com ", "selector=aaa :-abp-properties(abc) bbb", "domains=foo.com"]);
399 compareFilter("foo.com#?#:-abp-properties(|background-image: url(data:*))", ["type=elemhideemulation", "text=foo.com#?#:-abp-properties(|background-image: u rl(data:*))", "selectorDomains=foo.com", "selector=:-abp-properties(|background- image: url(data:*))", "domains=foo.com"]);
400
401 // Support element hiding emulation filters for localhost (#6931).
402 compareFilter("localhost#?#:-abp-properties(abc)", ["type=elemhideemulation" , "text=localhost#?#:-abp-properties(abc)", "selectorDomains=localhost", "select or=:-abp-properties(abc)", "domains=localhost"]);
403 compareFilter("localhost,~www.localhost#?#:-abp-properties(abc)", ["type=ele mhideemulation", "text=localhost,~www.localhost#?#:-abp-properties(abc)", "selec torDomains=localhost", "selector=:-abp-properties(abc)", "domains=localhost|~www .localhost"]);
404 compareFilter("~www.localhost,localhost#?#:-abp-properties(abc)", ["type=ele mhideemulation", "text=~www.localhost,localhost#?#:-abp-properties(abc)", "selec torDomains=localhost", "selector=:-abp-properties(abc)", "domains=localhost|~www .localhost"]);
405 });
406
407 it("Empty ElemeHide domains", () =>
408 {
409 let emptyDomainFilters = [
410 ",##selector", ",,,##selector", "~,foo.com##selector", "foo.com,##selector ",
411 ",foo.com##selector", "foo.com,~##selector",
412 "foo.com,,bar.com##selector", "foo.com,~,bar.com##selector"
413 ];
414
415 for (let filterText of emptyDomainFilters)
416 {
417 let filter = Filter.fromText(filterText);
418 assert.ok(filter instanceof InvalidFilter);
419 assert.equal(filter.reason, "filter_invalid_domain");
420 }
421 });
422
423 it("ElemHide rules with braces", () =>
424 {
425 compareFilter(
426 "###foo{color: red}", [
427 "type=elemhide",
428 "text=###foo{color: red}",
429 "selectorDomains=",
430 "selector=#foo{color: red}",
431 "domains="
268 ] 432 ]
269 ); 433 );
270 } 434 compareFilter(
271 checkElemHideEmulationFilterInvalid(""); 435 "foo.com#?#:-abp-properties(/margin: [3-4]{2}/)", [
272 checkElemHideEmulationFilterInvalid("~foo.com"); 436 "type=elemhideemulation",
273 checkElemHideEmulationFilterInvalid("~foo.com,~bar.com"); 437 "text=foo.com#?#:-abp-properties(/margin: [3-4]{2}/)",
274 checkElemHideEmulationFilterInvalid("foo"); 438 "selectorDomains=foo.com",
275 checkElemHideEmulationFilterInvalid("~foo.com,bar"); 439 "selector=:-abp-properties(/margin: [3-4]{2}/)",
276 440 "domains=foo.com"
277 test.done(); 441 ]
278 }; 442 );
279 443 });
280 exports.testFiltersWithState = function(test) 444
281 { 445 it("Snippet Filters", () =>
282 compareFilter(test, "blabla", ["type=filterlist", "text=blabla"]); 446 {
283 compareFilter( 447 compareFilter("foo.com#$#abc", ["type=snippet", "text=foo.com#$#abc", "scrip tDomains=foo.com", "script=abc", "domains=foo.com"]);
284 test, "blabla_default", ["type=filterlist", "text=blabla_default"], 448 compareFilter("foo.com,~bar.com#$#abc", ["type=snippet", "text=foo.com,~bar. com#$#abc", "scriptDomains=foo.com", "script=abc", "domains=foo.com|~bar.com"]);
285 filter => 449 compareFilter("foo.com,~bar#$#abc", ["type=snippet", "text=foo.com,~bar#$#ab c", "scriptDomains=foo.com", "script=abc", "domains=foo.com|~bar"]);
286 { 450 compareFilter("~foo.com,bar.com#$#abc", ["type=snippet", "text=~foo.com,bar. com#$#abc", "scriptDomains=bar.com", "script=abc", "domains=bar.com|~foo.com"]);
287 filter.disabled = false; 451 });
288 filter.hitCount = 0; 452
289 filter.lastHit = 0; 453 it("Filter normalization", () =>
290 } 454 {
291 ); 455 // Line breaks etc
292 compareFilter( 456 assert.equal(Filter.normalize("\n\t\nad\ns"),
293 test, "blabla_non_default", 457 "ads");
294 ["type=filterlist", "text=blabla_non_default", "disabled=true", "hitCount=12 ", "lastHit=20"], 458
295 filter => 459 // Comment filters
296 { 460 assert.equal(Filter.normalize(" ! fo o## bar "),
297 filter.disabled = true; 461 "! fo o## bar");
298 filter.hitCount = 12; 462
299 filter.lastHit = 20; 463 // Element hiding filters
300 } 464 assert.equal(Filter.normalize(" domain.c om## # sele ctor "),
301 ); 465 "domain.com### sele ctor");
302 466
303 test.done(); 467 // Element hiding emulation filters
304 }; 468 assert.equal(Filter.normalize(" domain.c om#?# # sele ctor "),
305 469 "domain.com#?## sele ctor");
306 exports.testSpecialCharacters = function(test) 470
307 { 471 // Incorrect syntax: the separator "#?#" cannot contain spaces; treated as a
308 compareFilter(test, "/ddd|f?a[s]d/", ["type=filterlist", "text=/ddd|f?a[s]d/", "regexp=ddd|f?a[s]d"]); 472 // regular filter instead
309 compareFilter(test, "*asdf*d**dd*", ["type=filterlist", "text=*asdf*d**dd*", " regexp=asdf.*d.*dd"]); 473 assert.equal(Filter.normalize(" domain.c om# ?#. sele ctor "),
310 compareFilter(test, "|*asd|f*d**dd*|", ["type=filterlist", "text=|*asd|f*d**dd *|", "regexp=^.*asd\\|f.*d.*dd.*$"]); 474 "domain.com#?#.selector");
311 compareFilter(test, "dd[]{}$%<>&()*d", ["type=filterlist", "text=dd[]{}$%<>&() *d", "regexp=dd\\[\\]\\{\\}\\$\\%\\<\\>\\&\\(\\).*d"]); 475 // Incorrect syntax: the separator "#?#" cannot contain spaces; treated as a n
312 476 // element hiding filter instead, because the "##" following the "?" is take n
313 // Leading and trailing wildcards should be left in for rewrite filters (#6868 ). 477 // to be the separator instead
314 compareFilter(test, "*asdf*d**dd*$rewrite=", ["type=filterlist", "text=*asdf*d **dd*$rewrite=", "regexp=.*asdf.*d.*dd.*", "rewrite=", "contentType=" + (default Types & ~(t.SCRIPT | t.SUBDOCUMENT | t.OBJECT | t.OBJECT_SUBREQUEST))]); 478 assert.equal(Filter.normalize(" domain.c om# ?##sele ctor "),
315 479 "domain.com#?##sele ctor");
316 compareFilter(test, "@@/ddd|f?a[s]d/", ["type=whitelist", "text=@@/ddd|f?a[s]d /", "regexp=ddd|f?a[s]d", "contentType=" + defaultTypes]); 480
317 compareFilter(test, "@@*asdf*d**dd*", ["type=whitelist", "text=@@*asdf*d**dd*" , "regexp=asdf.*d.*dd", "contentType=" + defaultTypes]); 481 // Element hiding exception filters
318 compareFilter(test, "@@|*asd|f*d**dd*|", ["type=whitelist", "text=@@|*asd|f*d* *dd*|", "regexp=^.*asd\\|f.*d.*dd.*$", "contentType=" + defaultTypes]); 482 assert.equal(Filter.normalize(" domain.c om#@# # sele ctor "),
319 compareFilter(test, "@@dd[]{}$%<>&()*d", ["type=whitelist", "text=@@dd[]{}$%<> &()*d", "regexp=dd\\[\\]\\{\\}\\$\\%\\<\\>\\&\\(\\).*d", "contentType=" + defaul tTypes]); 483 "domain.com#@## sele ctor");
320 484
321 test.done(); 485 // Incorrect syntax: the separator "#@#" cannot contain spaces; treated as a
322 }; 486 // regular filter instead (not an element hiding filter either!), because
323 487 // unlike the case with "# ?##" the "##" following the "@" is not considered
324 exports.testFilterOptions = function(test) 488 // to be a separator
325 { 489 assert.equal(Filter.normalize(" domain.c om# @## sele ctor "),
326 compareFilter(test, "bla$match-case,csp=first csp,script,other,third-party,dom ain=FOO.cOm,sitekey=foo", ["type=filterlist", "text=bla$match-case,csp=first csp ,script,other,third-party,domain=FOO.cOm,sitekey=foo", "matchCase=true", "conten tType=" + (t.SCRIPT | t.OTHER | t.CSP), "thirdParty=true", "domains=foo.com", "s itekeys=FOO", "csp=first csp"]); 490 "domain.com#@##selector");
327 compareFilter(test, "bla$~match-case,~csp=csp,~script,~other,~third-party,doma in=~bAr.coM", ["type=filterlist", "text=bla$~match-case,~csp=csp,~script,~other, ~third-party,domain=~bAr.coM", "contentType=" + (defaultTypes & ~(t.SCRIPT | t.O THER)), "thirdParty=false", "domains=~bar.com"]); 491
328 compareFilter(test, "@@bla$match-case,script,other,third-party,domain=foo.com| bar.com|~bAR.foO.Com|~Foo.Bar.com,csp=c s p,sitekey=foo|bar", ["type=whitelist", "text=@@bla$match-case,script,other,third-party,domain=foo.com|bar.com|~bAR.foO .Com|~Foo.Bar.com,csp=c s p,sitekey=foo|bar", "matchCase=true", "contentType=" + (t.SCRIPT | t.OTHER | t.CSP), "thirdParty=true", "domains=bar.com|foo.com|~bar. foo.com|~foo.bar.com", "sitekeys=BAR|FOO"]); 492 // Snippet filters
329 compareFilter(test, "@@bla$match-case,script,other,third-party,domain=foo.com| bar.com|~bar.foo.com|~foo.bar.com,sitekey=foo|bar", ["type=whitelist", "text=@@b la$match-case,script,other,third-party,domain=foo.com|bar.com|~bar.foo.com|~foo. bar.com,sitekey=foo|bar", "matchCase=true", "contentType=" + (t.SCRIPT | t.OTHER ), "thirdParty=true", "domains=bar.com|foo.com|~bar.foo.com|~foo.bar.com", "site keys=BAR|FOO"]); 493 assert.equal(Filter.normalize(" domain.c om#$# sni pp et "),
330 compareFilter(test, "||content.server.com/files/*.php$rewrite=$1", ["type=filt erlist", "text=||content.server.com/files/*.php$rewrite=$1", "regexp=^[\\w\\-]+: \\/+(?!\\/)(?:[^\\/]+\\.)?content\\.server\\.com\\/files\\/.*\\.php", "matchCase =false", "rewrite=$1", "contentType=" + (defaultTypes & ~(t.SCRIPT | t.SUBDOCUME NT | t.OBJECT | t.OBJECT_SUBREQUEST))]); 494 "domain.com#$#sni pp et");
331 495
332 compareFilter(test, "||example.com/ad.js$rewrite=abp-resource:noopjs,domain=fo o.com|bar.com", ["type=filterlist", "text=||example.com/ad.js$rewrite=abp-resour ce:noopjs,domain=foo.com|bar.com", "regexp=null", "matchCase=false", "rewrite=ab p-resource:noopjs", "contentType=" + (defaultTypes), "domains=bar.com|foo.com"]) ; 496 // Regular filters
333 compareFilter(test, "*example.com/ad.js$rewrite=abp-resource:noopjs,domain=foo .com|bar.com", ["type=filterlist", "text=*example.com/ad.js$rewrite=abp-resource :noopjs,domain=foo.com|bar.com", "regexp=null", "matchCase=false", "rewrite=abp- resource:noopjs", "contentType=" + (defaultTypes), "domains=bar.com|foo.com"]); 497 let normalized = Filter.normalize(
334 compareFilter(test, "||example.com/ad.js$rewrite=abp-resource:noopjs,~third-pa rty", ["type=filterlist", "text=||example.com/ad.js$rewrite=abp-resource:noopjs, ~third-party", "regexp=null", "matchCase=false", "rewrite=abp-resource:noopjs", "thirdParty=false", "contentType=" + (defaultTypes)]); 498 " b$l a$sitekey= foo ,domain= do main.com |foo .com,c sp= c s p "
335 499 );
336 // background and image should be the same for backwards compatibility 500 assert.equal(
337 compareFilter(test, "bla$image", ["type=filterlist", "text=bla$image", "conten tType=" + (t.IMAGE)]); 501 normalized,
338 compareFilter(test, "bla$background", ["type=filterlist", "text=bla$background ", "contentType=" + (t.IMAGE)]); 502 "b$la$sitekey=foo,domain=domain.com|foo.com,csp=c s p"
339 compareFilter(test, "bla$~image", ["type=filterlist", "text=bla$~image", "cont entType=" + (defaultTypes & ~t.IMAGE)]); 503 );
340 compareFilter(test, "bla$~background", ["type=filterlist", "text=bla$~backgrou nd", "contentType=" + (defaultTypes & ~t.IMAGE)]); 504 compareFilter(
341 505 normalized, [
342 compareFilter(test, "@@bla$~script,~other", ["type=whitelist", "text=@@bla$~sc ript,~other", "contentType=" + (defaultTypes & ~(t.SCRIPT | t.OTHER))]); 506 "type=filterlist",
343 compareFilter(test, "@@http://bla$~script,~other", ["type=whitelist", "text=@@ http://bla$~script,~other", "contentType=" + (defaultTypes & ~(t.SCRIPT | t.OTHE R))]); 507 "text=" + normalized,
344 compareFilter(test, "@@|ftp://bla$~script,~other", ["type=whitelist", "text=@@ |ftp://bla$~script,~other", "regexp=^ftp\\:\\/\\/bla", "contentType=" + (default Types & ~(t.SCRIPT | t.OTHER))]); 508 "csp=c s p",
345 compareFilter(test, "@@bla$~script,~other,document", ["type=whitelist", "text= @@bla$~script,~other,document", "contentType=" + (defaultTypes & ~(t.SCRIPT | t. OTHER) | t.DOCUMENT)]); 509 "domains=domain.com|foo.com",
346 compareFilter(test, "@@bla$~script,~other,~document", ["type=whitelist", "text =@@bla$~script,~other,~document", "contentType=" + (defaultTypes & ~(t.SCRIPT | t.OTHER))]); 510 "sitekeys=FOO",
347 compareFilter(test, "@@bla$document", ["type=whitelist", "text=@@bla$document" , "contentType=" + t.DOCUMENT]); 511 "contentType=" + t.CSP
348 compareFilter(test, "@@bla$~script,~other,elemhide", ["type=whitelist", "text= @@bla$~script,~other,elemhide", "contentType=" + (defaultTypes & ~(t.SCRIPT | t. OTHER) | t.ELEMHIDE)]); 512 ]
349 compareFilter(test, "@@bla$~script,~other,~elemhide", ["type=whitelist", "text =@@bla$~script,~other,~elemhide", "contentType=" + (defaultTypes & ~(t.SCRIPT | t.OTHER))]); 513 );
350 compareFilter(test, "@@bla$elemhide", ["type=whitelist", "text=@@bla$elemhide" , "contentType=" + t.ELEMHIDE]); 514
351 515 // Some $csp edge cases
352 compareFilter(test, "@@bla$~script,~other,donottrack", ["type=invalid", "text= @@bla$~script,~other,donottrack", "reason=filter_unknown_option"]); 516 assert.equal(Filter.normalize("$csp= "),
353 compareFilter(test, "@@bla$~script,~other,~donottrack", ["type=invalid", "text =@@bla$~script,~other,~donottrack", "reason=filter_unknown_option"]); 517 "$csp=");
354 compareFilter(test, "@@bla$donottrack", ["type=invalid", "text=@@bla$donottrac k", "reason=filter_unknown_option"]); 518 assert.equal(Filter.normalize("$csp= c s p"),
355 compareFilter(test, "@@bla$foobar", ["type=invalid", "text=@@bla$foobar", "rea son=filter_unknown_option"]); 519 "$csp=c s p");
356 compareFilter(test, "@@bla$image,foobar", ["type=invalid", "text=@@bla$image,f oobar", "reason=filter_unknown_option"]); 520 assert.equal(Filter.normalize("$$csp= c s p"),
357 compareFilter(test, "@@bla$foobar,image", ["type=invalid", "text=@@bla$foobar, image", "reason=filter_unknown_option"]); 521 "$$csp=c s p");
358 522 assert.equal(Filter.normalize("$$$csp= c s p"),
359 compareFilter(test, "bla$csp", ["type=invalid", "text=bla$csp", "reason=filter _invalid_csp"]); 523 "$$$csp=c s p");
360 compareFilter(test, "bla$csp=", ["type=invalid", "text=bla$csp=", "reason=filt er_invalid_csp"]); 524 assert.equal(Filter.normalize("foo?csp=b a r$csp=script-src 'self'"),
361 525 "foo?csp=bar$csp=script-src 'self'");
362 // Blank CSP values are allowed for whitelist filters. 526 assert.equal(Filter.normalize("foo$bar=c s p = ba z,cs p = script-src 'self '"),
363 compareFilter(test, "@@bla$csp", ["type=whitelist", "text=@@bla$csp", "content Type=" + t.CSP]); 527 "foo$bar=csp=baz,csp=script-src 'self'");
364 compareFilter(test, "@@bla$csp=", ["type=whitelist", "text=@@bla$csp=", "conte ntType=" + t.CSP]); 528 assert.equal(Filter.normalize("foo$csp=c s p csp= ba z,cs p = script-src ' self'"),
365 529 "foo$csp=c s p csp= ba z,csp=script-src 'self'");
366 compareFilter(test, "bla$csp=report-uri", ["type=invalid", "text=bla$csp=repor t-uri", "reason=filter_invalid_csp"]); 530 assert.equal(Filter.normalize("foo$csp=bar,$c sp=c s p"),
367 compareFilter(test, "bla$csp=foo,csp=report-to", ["type=invalid", "text=bla$cs p=foo,csp=report-to", "reason=filter_invalid_csp"]); 531 "foo$csp=bar,$csp=c s p");
368 compareFilter(test, "bla$csp=foo,csp=referrer foo", ["type=invalid", "text=bla $csp=foo,csp=referrer foo", "reason=filter_invalid_csp"]); 532 assert.equal(Filter.normalize(" f o o $ bar $csp=ba r"),
369 compareFilter(test, "bla$csp=foo,csp=base-uri", ["type=invalid", "text=bla$csp =foo,csp=base-uri", "reason=filter_invalid_csp"]); 533 "foo$bar$csp=ba r");
370 compareFilter(test, "bla$csp=foo,csp=upgrade-insecure-requests", ["type=invali d", "text=bla$csp=foo,csp=upgrade-insecure-requests", "reason=filter_invalid_csp "]); 534 assert.equal(Filter.normalize("f $ o $ o $ csp=f o o "),
371 compareFilter(test, "bla$csp=foo,csp=ReFeRReR", ["type=invalid", "text=bla$csp =foo,csp=ReFeRReR", "reason=filter_invalid_csp"]); 535 "f$o$o$csp=f o o");
372 536 assert.equal(Filter.normalize("/foo$/$ csp = script-src http://example.com/ ?$1=1&$2=2&$3=3"),
373 test.done(); 537 "/foo$/$csp=script-src http://example.com/?$1=1&$2=2&$3=3");
374 }; 538 assert.equal(Filter.normalize("||content.server.com/files/*.php$rewrite= $1" ),
375 539 "||content.server.com/files/*.php$rewrite=$1");
376 exports.testElementHidingRules = function(test) 540 });
377 { 541
378 compareFilter(test, "##ddd", ["type=elemhide", "text=##ddd", "selector=ddd"]); 542 it("Filter rewrite option", () =>
379 compareFilter(test, "##body > div:first-child", ["type=elemhide", "text=##body > div:first-child", "selector=body > div:first-child"]); 543 {
380 compareFilter(test, "fOO##ddd", ["type=elemhide", "text=fOO##ddd", "selectorDo mains=foo", "selector=ddd", "domains=foo"]); 544 let text = "/(content\\.server\\/file\\/.*\\.txt)\\?.*$/$rewrite=$1";
381 compareFilter(test, "Foo,bAr##ddd", ["type=elemhide", "text=Foo,bAr##ddd", "se lectorDomains=foo,bar", "selector=ddd", "domains=bar|foo"]); 545
382 compareFilter(test, "foo,~baR##ddd", ["type=elemhide", "text=foo,~baR##ddd", " selectorDomains=foo", "selector=ddd", "domains=foo|~bar"]); 546 let filter = Filter.fromText(text);
383 compareFilter(test, "foo,~baz,bar##ddd", ["type=elemhide", "text=foo,~baz,bar# #ddd", "selectorDomains=foo,bar", "selector=ddd", "domains=bar|foo|~baz"]); 547
384 548 assert.equal(filter.rewrite, "$1");
385 test.done(); 549 // no rewrite occured: didn't match.
386 }; 550 assert.equal(filter.rewriteUrl("foo"), "foo");
387 551 // rewrite occured: matched.
388 exports.testElementHidingExceptions = function(test) 552 assert.equal(filter.rewriteUrl("http://content.server/file/foo.txt?bar"),
389 { 553 "http://content.server/file/foo.txt");
390 compareFilter(test, "#@#ddd", ["type=elemhideexception", "text=#@#ddd", "selec tor=ddd"]); 554
391 compareFilter(test, "#@#body > div:first-child", ["type=elemhideexception", "t ext=#@#body > div:first-child", "selector=body > div:first-child"]); 555 // checking for same origin.
392 compareFilter(test, "fOO#@#ddd", ["type=elemhideexception", "text=fOO#@#ddd", "selectorDomains=foo", "selector=ddd", "domains=foo"]); 556 let rewriteDiffOrigin =
393 compareFilter(test, "Foo,bAr#@#ddd", ["type=elemhideexception", "text=Foo,bAr# @#ddd", "selectorDomains=foo,bar", "selector=ddd", "domains=bar|foo"]);
394 compareFilter(test, "foo,~baR#@#ddd", ["type=elemhideexception", "text=foo,~ba R#@#ddd", "selectorDomains=foo", "selector=ddd", "domains=foo|~bar"]);
395 compareFilter(test, "foo,~baz,bar#@#ddd", ["type=elemhideexception", "text=foo ,~baz,bar#@#ddd", "selectorDomains=foo,bar", "selector=ddd", "domains=bar|foo|~b az"]);
396
397 test.done();
398 };
399
400 exports.testElemHideEmulationFilters = function(test)
401 {
402 // Check valid domain combinations
403 compareFilter(test, "fOO.cOm#?#:-abp-properties(abc)", ["type=elemhideemulatio n", "text=fOO.cOm#?#:-abp-properties(abc)", "selectorDomains=foo.com", "selector =:-abp-properties(abc)", "domains=foo.com"]);
404 compareFilter(test, "Foo.com,~bAr.com#?#:-abp-properties(abc)", ["type=elemhid eemulation", "text=Foo.com,~bAr.com#?#:-abp-properties(abc)", "selectorDomains=f oo.com", "selector=:-abp-properties(abc)", "domains=foo.com|~bar.com"]);
405 compareFilter(test, "foo.com,~baR#?#:-abp-properties(abc)", ["type=elemhideemu lation", "text=foo.com,~baR#?#:-abp-properties(abc)", "selectorDomains=foo.com", "selector=:-abp-properties(abc)", "domains=foo.com|~bar"]);
406 compareFilter(test, "~foo.com,bar.com#?#:-abp-properties(abc)", ["type=elemhid eemulation", "text=~foo.com,bar.com#?#:-abp-properties(abc)", "selectorDomains=b ar.com", "selector=:-abp-properties(abc)", "domains=bar.com|~foo.com"]);
407
408 // Check some special cases
409 compareFilter(test, "#?#:-abp-properties(abc)", ["type=invalid", "text=#?#:-ab p-properties(abc)", "reason=filter_elemhideemulation_nodomain"]);
410 compareFilter(test, "foo.com#?#abc", ["type=elemhideemulation", "text=foo.com# ?#abc", "selectorDomains=foo.com", "selector=abc", "domains=foo.com"]);
411 compareFilter(test, "foo.com#?#:-abp-foobar(abc)", ["type=elemhideemulation", "text=foo.com#?#:-abp-foobar(abc)", "selectorDomains=foo.com", "selector=:-abp-f oobar(abc)", "domains=foo.com"]);
412 compareFilter(test, "foo.com#?#aaa :-abp-properties(abc) bbb", ["type=elemhide emulation", "text=foo.com#?#aaa :-abp-properties(abc) bbb", "selectorDomains=foo .com", "selector=aaa :-abp-properties(abc) bbb", "domains=foo.com"]);
413 compareFilter(test, "foo.com#?#:-abp-properties(|background-image: url(data:*) )", ["type=elemhideemulation", "text=foo.com#?#:-abp-properties(|background-imag e: url(data:*))", "selectorDomains=foo.com", "selector=:-abp-properties(|backgro und-image: url(data:*))", "domains=foo.com"]);
414
415 // Support element hiding emulation filters for localhost (#6931).
416 compareFilter(test, "localhost#?#:-abp-properties(abc)", ["type=elemhideemulat ion", "text=localhost#?#:-abp-properties(abc)", "selectorDomains=localhost", "se lector=:-abp-properties(abc)", "domains=localhost"]);
417 compareFilter(test, "localhost,~www.localhost#?#:-abp-properties(abc)", ["type =elemhideemulation", "text=localhost,~www.localhost#?#:-abp-properties(abc)", "s electorDomains=localhost", "selector=:-abp-properties(abc)", "domains=localhost| ~www.localhost"]);
418 compareFilter(test, "~www.localhost,localhost#?#:-abp-properties(abc)", ["type =elemhideemulation", "text=~www.localhost,localhost#?#:-abp-properties(abc)", "s electorDomains=localhost", "selector=:-abp-properties(abc)", "domains=localhost| ~www.localhost"]);
419
420 test.done();
421 };
422
423 exports.testEmptyElemHideDomains = function(test)
424 {
425 let emptyDomainFilters = [
426 ",##selector", ",,,##selector", "~,foo.com##selector", "foo.com,##selector",
427 ",foo.com##selector", "foo.com,~##selector",
428 "foo.com,,bar.com##selector", "foo.com,~,bar.com##selector"
429 ];
430
431 for (let filterText of emptyDomainFilters)
432 {
433 let filter = Filter.fromText(filterText);
434 test.ok(filter instanceof InvalidFilter);
435 test.equal(filter.reason, "filter_invalid_domain");
436 }
437
438 test.done();
439 };
440
441 exports.testElemHideRulesWithBraces = function(test)
442 {
443 compareFilter(
444 test, "###foo{color: red}", [
445 "type=elemhide",
446 "text=###foo{color: red}",
447 "selectorDomains=",
448 "selector=#foo{color: red}",
449 "domains="
450 ]
451 );
452 compareFilter(
453 test, "foo.com#?#:-abp-properties(/margin: [3-4]{2}/)", [
454 "type=elemhideemulation",
455 "text=foo.com#?#:-abp-properties(/margin: [3-4]{2}/)",
456 "selectorDomains=foo.com",
457 "selector=:-abp-properties(/margin: [3-4]{2}/)",
458 "domains=foo.com"
459 ]
460 );
461 test.done();
462 };
463
464 exports.testSnippetFilters = function(test)
465 {
466 compareFilter(test, "foo.com#$#abc", ["type=snippet", "text=foo.com#$#abc", "s criptDomains=foo.com", "script=abc", "domains=foo.com"]);
467 compareFilter(test, "foo.com,~bar.com#$#abc", ["type=snippet", "text=foo.com,~ bar.com#$#abc", "scriptDomains=foo.com", "script=abc", "domains=foo.com|~bar.com "]);
468 compareFilter(test, "foo.com,~bar#$#abc", ["type=snippet", "text=foo.com,~bar# $#abc", "scriptDomains=foo.com", "script=abc", "domains=foo.com|~bar"]);
469 compareFilter(test, "~foo.com,bar.com#$#abc", ["type=snippet", "text=~foo.com, bar.com#$#abc", "scriptDomains=bar.com", "script=abc", "domains=bar.com|~foo.com "]);
470
471 test.done();
472 };
473
474 exports.testFilterNormalization = function(test)
475 {
476 // Line breaks etc
477 test.equal(Filter.normalize("\n\t\nad\ns"),
478 "ads");
479
480 // Comment filters
481 test.equal(Filter.normalize(" ! fo o## bar "),
482 "! fo o## bar");
483
484 // Element hiding filters
485 test.equal(Filter.normalize(" domain.c om## # sele ctor "),
486 "domain.com### sele ctor");
487
488 // Element hiding emulation filters
489 test.equal(Filter.normalize(" domain.c om#?# # sele ctor "),
490 "domain.com#?## sele ctor");
491
492 // Incorrect syntax: the separator "#?#" cannot contain spaces; treated as a
493 // regular filter instead
494 test.equal(Filter.normalize(" domain.c om# ?#. sele ctor "),
495 "domain.com#?#.selector");
496 // Incorrect syntax: the separator "#?#" cannot contain spaces; treated as an
497 // element hiding filter instead, because the "##" following the "?" is taken
498 // to be the separator instead
499 test.equal(Filter.normalize(" domain.c om# ?##sele ctor "),
500 "domain.com#?##sele ctor");
501
502 // Element hiding exception filters
503 test.equal(Filter.normalize(" domain.c om#@# # sele ctor "),
504 "domain.com#@## sele ctor");
505
506 // Incorrect syntax: the separator "#@#" cannot contain spaces; treated as a
507 // regular filter instead (not an element hiding filter either!), because
508 // unlike the case with "# ?##" the "##" following the "@" is not considered
509 // to be a separator
510 test.equal(Filter.normalize(" domain.c om# @## sele ctor "),
511 "domain.com#@##selector");
512
513 // Snippet filters
514 test.equal(Filter.normalize(" domain.c om#$# sni pp et "),
515 "domain.com#$#sni pp et");
516
517 // Regular filters
518 let normalized = Filter.normalize(
519 " b$l a$sitekey= foo ,domain= do main.com |foo .com,c sp= c s p "
520 );
521 test.equal(
522 normalized,
523 "b$la$sitekey=foo,domain=domain.com|foo.com,csp=c s p"
524 );
525 compareFilter(
526 test, normalized, [
527 "type=filterlist",
528 "text=" + normalized,
529 "csp=c s p",
530 "domains=domain.com|foo.com",
531 "sitekeys=FOO",
532 "contentType=" + t.CSP
533 ]
534 );
535
536 // Some $csp edge cases
537 test.equal(Filter.normalize("$csp= "),
538 "$csp=");
539 test.equal(Filter.normalize("$csp= c s p"),
540 "$csp=c s p");
541 test.equal(Filter.normalize("$$csp= c s p"),
542 "$$csp=c s p");
543 test.equal(Filter.normalize("$$$csp= c s p"),
544 "$$$csp=c s p");
545 test.equal(Filter.normalize("foo?csp=b a r$csp=script-src 'self'"),
546 "foo?csp=bar$csp=script-src 'self'");
547 test.equal(Filter.normalize("foo$bar=c s p = ba z,cs p = script-src 'self'"),
548 "foo$bar=csp=baz,csp=script-src 'self'");
549 test.equal(Filter.normalize("foo$csp=c s p csp= ba z,cs p = script-src 'self '"),
550 "foo$csp=c s p csp= ba z,csp=script-src 'self'");
551 test.equal(Filter.normalize("foo$csp=bar,$c sp=c s p"),
552 "foo$csp=bar,$csp=c s p");
553 test.equal(Filter.normalize(" f o o $ bar $csp=ba r"),
554 "foo$bar$csp=ba r");
555 test.equal(Filter.normalize("f $ o $ o $ csp=f o o "),
556 "f$o$o$csp=f o o");
557 test.equal(Filter.normalize("/foo$/$ csp = script-src http://example.com/?$1= 1&$2=2&$3=3"),
558 "/foo$/$csp=script-src http://example.com/?$1=1&$2=2&$3=3");
559 test.equal(Filter.normalize("||content.server.com/files/*.php$rewrite= $1"),
560 "||content.server.com/files/*.php$rewrite=$1");
561 test.done();
562 };
563
564 exports.testFilterRewriteOption = function(test)
565 {
566 let text = "/(content\\.server\\/file\\/.*\\.txt)\\?.*$/$rewrite=$1";
567
568 let filter = Filter.fromText(text);
569
570 test.equal(filter.rewrite, "$1");
571 // no rewrite occured: didn't match.
572 test.equal(filter.rewriteUrl("foo"), "foo");
573 // rewrite occured: matched.
574 test.equal(filter.rewriteUrl("http://content.server/file/foo.txt?bar"),
575 "http://content.server/file/foo.txt");
576
577 // checking for same origin.
578 let rewriteDiffOrigin =
579 "/content\\.server(\\/file\\/.*\\.txt)\\?.*$/$rewrite=foo.com$1"; 557 "/content\\.server(\\/file\\/.*\\.txt)\\?.*$/$rewrite=foo.com$1";
580 let filterDiffOrigin = Filter.fromText(rewriteDiffOrigin); 558 let filterDiffOrigin = Filter.fromText(rewriteDiffOrigin);
581 559
582 // no rewrite occured because of a different origin. 560 // no rewrite occured because of a different origin.
583 test.equal( 561 assert.equal(
584 filterDiffOrigin.rewriteUrl("http://content.server/file/foo.txt?bar"), 562 filterDiffOrigin.rewriteUrl("http://content.server/file/foo.txt?bar"),
585 "http://content.server/file/foo.txt?bar" 563 "http://content.server/file/foo.txt?bar"
586 ); 564 );
587 565
588 // relative path. 566 // relative path.
589 let rewriteRelative = "/(\\/file\\/.*\\.txt)\\?.*$/$rewrite=$1/disable"; 567 let rewriteRelative = "/(\\/file\\/.*\\.txt)\\?.*$/$rewrite=$1/disable";
590 let filterRelative = Filter.fromText(rewriteRelative); 568 let filterRelative = Filter.fromText(rewriteRelative);
591 569
592 test.equal( 570 assert.equal(
593 filterRelative.rewriteUrl("http://content.server/file/foo.txt?bar"), 571 filterRelative.rewriteUrl("http://content.server/file/foo.txt?bar"),
594 "http://content.server/file/foo.txt/disable" 572 "http://content.server/file/foo.txt/disable"
595 ); 573 );
596 test.equal( 574 assert.equal(
597 filterRelative.rewriteUrl("http://example.com/file/foo.txt?bar"), 575 filterRelative.rewriteUrl("http://example.com/file/foo.txt?bar"),
598 "http://example.com/file/foo.txt/disable" 576 "http://example.com/file/foo.txt/disable"
599 ); 577 );
600 578
601 // Example from https://github.com/uBlockOrigin/uBlock-issues/issues/46#issuec omment-391190533 579 // Example from https://github.com/uBlockOrigin/uBlock-issues/issues/46#issu ecomment-391190533
602 // The rewrite shouldn't happen. 580 // The rewrite shouldn't happen.
603 let rewriteEvil = "/(^https?:\\/\\/[^/])/$script,rewrite=$1.evil.com"; 581 let rewriteEvil = "/(^https?:\\/\\/[^/])/$script,rewrite=$1.evil.com";
604 let filterEvil = Filter.fromText(rewriteEvil); 582 let filterEvil = Filter.fromText(rewriteEvil);
605 583
606 test.equal( 584 assert.equal(
607 filterEvil.rewriteUrl("https://www.adblockplus.org/script.js"), 585 filterEvil.rewriteUrl("https://www.adblockplus.org/script.js"),
608 "https://www.adblockplus.org/script.js" 586 "https://www.adblockplus.org/script.js"
609 ); 587 );
610 588
611 // Strip. 589 // Strip.
612 let rewriteStrip = "tag$rewrite="; 590 let rewriteStrip = "tag$rewrite=";
613 let filterStrip = Filter.fromText(rewriteStrip); 591 let filterStrip = Filter.fromText(rewriteStrip);
614 592
615 test.equal(filterStrip.rewrite, ""); 593 assert.equal(filterStrip.rewrite, "");
616 test.equal( 594 assert.equal(
617 filterStrip.rewriteUrl("http://example.com/?tag"), 595 filterStrip.rewriteUrl("http://example.com/?tag"),
618 "http://example.com/?" 596 "http://example.com/?"
619 ); 597 );
620 598 });
621 test.done(); 599
622 }; 600 it("Domain map deduplication", () =>
623 601 {
624 exports.testDomainMapDeduplication = function(test) 602 let filter1 = Filter.fromText("foo$domain=blocking.example.com");
625 { 603 let filter2 = Filter.fromText("bar$domain=blocking.example.com");
626 let filter1 = Filter.fromText("foo$domain=blocking.example.com"); 604 let filter3 = Filter.fromText("elemhide.example.com##.foo");
627 let filter2 = Filter.fromText("bar$domain=blocking.example.com"); 605 let filter4 = Filter.fromText("elemhide.example.com##.bar");
628 let filter3 = Filter.fromText("elemhide.example.com##.foo"); 606
629 let filter4 = Filter.fromText("elemhide.example.com##.bar"); 607 // This compares the references to make sure that both refer to the same
630 608 // object (#6815).
631 // This compares the references to make sure that both refer to the same 609
632 // object (#6815). 610 assert.equal(filter1.domains, filter2.domains);
633 611 assert.equal(filter3.domains, filter4.domains);
634 test.equal(filter1.domains, filter2.domains); 612
635 test.equal(filter3.domains, filter4.domains); 613 let filter5 = Filter.fromText("bar$domain=www.example.com");
636 614 let filter6 = Filter.fromText("www.example.com##.bar");
637 let filter5 = Filter.fromText("bar$domain=www.example.com"); 615
638 let filter6 = Filter.fromText("www.example.com##.bar"); 616 assert.notEqual(filter2.domains, filter5.domains);
639 617 assert.notEqual(filter4.domains, filter6.domains);
640 test.notEqual(filter2.domains, filter5.domains); 618 });
641 test.notEqual(filter4.domains, filter6.domains); 619 });
642
643 test.done();
644 };
OLDNEW
« no previous file with comments | « test/elemHide.js ('k') | test/filterListener.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld