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 13 matching lines...) Expand all Loading... |
114 }; | 167 }; |
115 | 168 |
116 exports.testSubscriptionDefaults = function(test) | 169 exports.testSubscriptionDefaults = function(test) |
117 { | 170 { |
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 ["", "!test"], | 177 [null, "!test"], |
125 ["", "/??/"], | 178 [null, "/??/"], |
126 ["blocking whitelist", "test", "@@test"], | 179 ["blocking whitelist", "test", "@@test"], |
127 ["blocking elemhide", "test", "##test"] | 180 ["blocking elemhide", "test", "##test"] |
128 ]; | 181 ]; |
129 | 182 |
130 for (let [defaults, ...filters] of tests) | 183 for (let [defaults, ...filters] of tests) |
131 { | 184 { |
132 let expected = ["url=~user~" + filters.join("~")]; | 185 withNAD(1, testSerializeParse)(test, createSubscription("~user~" + filters.j
oin("~"), |
133 if (defaults) | 186 subscription => |
134 expected.push("defaults= " + defaults); | |
135 compareSubscription(test, "~user~" + filters.join("~"), expected, subscripti
on => | |
136 { | |
137 for (let text of filters) | |
138 { | 187 { |
139 let filter = Filter.fromText(text); | 188 for (let text of filters) |
140 subscription.makeDefaultFor(filter); | 189 withNAD(0, subscription.makeDefaultFor, subscription)(Filter.fromText(
text)); |
141 filter.delete(); | 190 }), (serializedData) => |
142 } | 191 { |
143 }); | 192 let foundDefaults = null; |
| 193 for (let line of serializedData.split("\n")) |
| 194 { |
| 195 if (line.startsWith("defaults=")) |
| 196 { |
| 197 foundDefaults = line; |
| 198 break; |
| 199 } |
| 200 } |
| 201 test.equal(foundDefaults, defaults ? "defaults= " + defaults : null, "un
expected serialization of defaults"); |
| 202 }); |
144 } | 203 } |
145 test.done(); | 204 test.done(); |
146 }; | 205 }; |
147 | 206 |
148 exports.testGC = function(test) | 207 exports.testGC = function(test) |
149 { | 208 { |
150 let subscription1 = Subscription.fromURL("http://example.com/"); | 209 let subscription1 = Subscription.fromURL("http://example.com/"); |
151 test.equal(subscription1.lastDownload, 0, "Initial download time"); | 210 test.equal(subscription1.lastDownload, 0, "Initial download time"); |
152 | 211 |
153 subscription1.lastDownload = 432; | 212 subscription1.lastDownload = 432; |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
234 checkFilterAt(0, "filter2", "First filter after releasing filter references"); | 293 checkFilterAt(0, "filter2", "First filter after releasing filter references"); |
235 checkFilterAt(1, "filter1", "Second filter after releasing filter references")
; | 294 checkFilterAt(1, "filter1", "Second filter after releasing filter references")
; |
236 | 295 |
237 subscription.delete(); | 296 subscription.delete(); |
238 | 297 |
239 test.done(); | 298 test.done(); |
240 }; | 299 }; |
241 | 300 |
242 exports.testFilterSerialization = function(test) | 301 exports.testFilterSerialization = function(test) |
243 { | 302 { |
244 let filter1 = Filter.fromText("filter1"); | 303 withNAD([0, 1, 2], (subscription, filter1, filter2) => |
245 let filter2 = Filter.fromText("filter2"); | 304 { |
| 305 testSerializeParse(test, subscription, (serializedData) => |
| 306 test.ok(!serializedData.includes("[Subscription filters]"), "Unexpected fi
lters section") |
| 307 ); |
246 | 308 |
247 let subscription = Subscription.fromURL("~user~12345"); | 309 subscription.insertFilterAt(filter1, 0); |
248 test.equal(subscription.serializeFilters(), "", "No filters added"); | 310 subscription.insertFilterAt(filter1, 1); |
| 311 subscription.insertFilterAt(filter2, 1); |
249 | 312 |
250 subscription.insertFilterAt(filter1, 0); | 313 testSerializeParse(test, subscription, (serializedData) => |
251 subscription.insertFilterAt(filter1, 1); | 314 test.ok(serializedData.includes("[Subscription filters]\nfilter1\nfilter2\
nfilter1\n"), "Three filters added") |
252 subscription.insertFilterAt(filter2, 1); | 315 ); |
253 test.equal(subscription.serializeFilters(), "[Subscription filters]\nfilter1\n
filter2\nfilter1\n", "Three filters added"); | |
254 | 316 |
255 subscription.removeFilterAt(0); | 317 subscription.removeFilterAt(0); |
256 test.equal(subscription.serializeFilters(), "[Subscription filters]\nfilter2\n
filter1\n", "One filter removed"); | 318 testSerializeParse(test, subscription, (serializedData) => |
257 | 319 test.ok(serializedData.includes("[Subscription filters]\nfilter2\nfilter1\
n"), "One filter removed") |
258 subscription.delete(); | 320 ); |
259 filter1.delete(); | 321 })(Subscription.fromURL("~user~12345"), Filter.fromText("filter1"), Filter.fro
mText("filter2")); |
260 filter2.delete(); | |
261 | 322 |
262 test.done(); | 323 test.done(); |
263 }; | 324 }; |
264 | 325 |
| 326 exports.testEscapingFilterSerialization = function(test) |
| 327 { |
| 328 withNAD(0, subscription => |
| 329 { |
| 330 let subsriptionAddFilter = withNAD(0, subscription.insertFilterAt, subscript
ion); |
| 331 |
| 332 subsriptionAddFilter(Filter.fromText("[[x[x[[]x]"), 0); |
| 333 subsriptionAddFilter(Filter.fromText("x[[x[x[[]x]x"), 1); |
| 334 subsriptionAddFilter(Filter.fromText("x\\[]x"), 2); |
| 335 |
| 336 withNAD(1, testSerializeParse)(test, subscription, (serializedData) => |
| 337 test.ok(serializedData.includes("[Subscription filters]\n\\[\\[x\\[x\\[\\[
]x]\nx\\[\\[x\\[x\\[\\[]x]x\nx\\\\[]x\n"), "Filters should be escaped")); |
| 338 })(Subscription.fromURL("~user~12345")); |
| 339 test.done(); |
| 340 }; |
| 341 |
265 exports.testNotifications = function(test) | 342 exports.testNotifications = function(test) |
266 { | 343 { |
267 function checkNotifications(action, expected, message) | 344 function checkNotifications(action, expected, message) |
268 { | 345 { |
269 let result = null; | 346 let result = null; |
270 let listener = (topic, subscription) => | 347 let listener = (topic, subscription) => |
271 { | 348 { |
272 if (result) | 349 if (result) |
273 test.ok(false, "Got more that one notification - " + message); | 350 test.ok(false, "Got more that one notification - " + message); |
274 else | 351 else |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
361 subscription.errors++; | 438 subscription.errors++; |
362 }, ["subscription.errors", "http://example.com/"], "Increasing subscription.er
rors"); | 439 }, ["subscription.errors", "http://example.com/"], "Increasing subscription.er
rors"); |
363 checkNotifications(() => | 440 checkNotifications(() => |
364 { | 441 { |
365 subscription.errors = 0; | 442 subscription.errors = 0; |
366 }, ["subscription.errors", "http://example.com/"], "Resetting subscription.err
os"); | 443 }, ["subscription.errors", "http://example.com/"], "Resetting subscription.err
os"); |
367 | 444 |
368 subscription.delete(); | 445 subscription.delete(); |
369 test.done(); | 446 test.done(); |
370 }; | 447 }; |
OLD | NEW |