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