OLD | NEW |
1 /* | 1 /* |
2 * This file is part of Adblock Plus <https://adblockplus.org/>, | 2 * This file is part of Adblock Plus <https://adblockplus.org/>, |
3 * Copyright (C) 2006-2017 eyeo GmbH | 3 * Copyright (C) 2006-2017 eyeo GmbH |
4 * | 4 * |
5 * Adblock Plus is free software: you can redistribute it and/or modify | 5 * Adblock Plus is free software: you can redistribute it and/or modify |
6 * it under the terms of the GNU General Public License version 3 as | 6 * it under the terms of the GNU General Public License version 3 as |
7 * published by the Free Software Foundation. | 7 * published by the Free Software Foundation. |
8 * | 8 * |
9 * Adblock Plus is distributed in the hope that it will be useful, | 9 * Adblock Plus is distributed in the hope that it will be useful, |
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of | 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
12 * GNU General Public License for more details. | 12 * GNU General Public License for more details. |
13 * | 13 * |
14 * You should have received a copy of the GNU General Public License | 14 * You should have received a copy of the GNU General Public License |
15 * along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>. | 15 * along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>. |
16 */ | 16 */ |
17 | 17 |
18 "use strict"; | 18 "use strict"; |
19 | 19 |
20 const {createSandbox, unexpectedError} = require("./_common"); | 20 const {createSandbox, unexpectedError} = require("./_common"); |
21 | 21 |
22 let Filter = null; | 22 let Filter = null; |
23 let FilterNotifier = null; | 23 let FilterNotifier = null; |
24 let FilterStorage = null; | 24 let FilterStorage = null; |
25 let IO = null; | 25 let IO = null; |
26 let Prefs = null; | 26 let Prefs = null; |
27 let Subscription = null; | 27 let Subscription = null; |
28 let ExternalSubscription = null; | 28 let ExternalSubscription = null; |
| 29 let dataFile = null; |
29 | 30 |
30 exports.setUp = function(callback) | 31 exports.setUp = function(callback) |
31 { | 32 { |
32 let sandboxedRequire = createSandbox(); | 33 let sandboxedRequire = createSandbox(); |
33 ( | 34 ( |
34 {Filter} = sandboxedRequire("../lib/filterClasses"), | 35 {Filter} = sandboxedRequire("../lib/filterClasses"), |
35 {FilterNotifier} = sandboxedRequire("../lib/filterNotifier"), | 36 {FilterNotifier} = sandboxedRequire("../lib/filterNotifier"), |
36 {FilterStorage} = sandboxedRequire("../lib/filterStorage"), | 37 {FilterStorage} = sandboxedRequire("../lib/filterStorage"), |
37 {IO} = sandboxedRequire("./stub-modules/io"), | 38 {IO} = sandboxedRequire("./stub-modules/io"), |
38 {Prefs} = sandboxedRequire("./stub-modules/prefs"), | 39 {Prefs} = sandboxedRequire("./stub-modules/prefs"), |
39 {Subscription, ExternalSubscription} = sandboxedRequire("../lib/subscription
Classes") | 40 {Subscription, ExternalSubscription} = sandboxedRequire("../lib/subscription
Classes") |
40 ); | 41 ); |
41 | 42 |
42 FilterStorage.addSubscription(Subscription.fromURL("~fl~")); | 43 Prefs.patternsfile = "patterns.ini"; |
| 44 dataFile = IO.resolveFilePath(Prefs.patternsfile); |
| 45 |
| 46 FilterStorage.addFilter(Filter.fromText("foobar")); |
43 callback(); | 47 callback(); |
44 }; | 48 }; |
45 | 49 |
46 let testData = new Promise((resolve, reject) => | 50 let testData = new Promise((resolve, reject) => |
47 { | 51 { |
48 const fs = require("fs"); | 52 const fs = require("fs"); |
49 const path = require("path"); | 53 const path = require("path"); |
50 let datapath = path.resolve(__dirname, "data", "patterns.ini"); | 54 let datapath = path.resolve(__dirname, "data", "patterns.ini"); |
51 | 55 |
52 fs.readFile(datapath, "utf-8", (error, data) => | 56 fs.readFile(datapath, "utf-8", (error, data) => |
53 { | 57 { |
54 if (error) | 58 if (error) |
55 reject(error); | 59 reject(error); |
56 else | 60 else |
57 resolve(data); | 61 resolve(data); |
58 }); | 62 }); |
59 }); | 63 }); |
60 | 64 |
61 function loadFilters(file) | 65 function loadFilters() |
62 { | 66 { |
63 FilterStorage.loadFromDisk(file); | 67 FilterStorage.loadFromDisk(); |
64 return FilterNotifier.once("load"); | 68 return FilterNotifier.once("load"); |
65 } | 69 } |
66 | 70 |
67 function saveFilters(file) | 71 function saveFilters() |
68 { | 72 { |
69 FilterStorage.saveToDisk(file); | 73 FilterStorage.saveToDisk(); |
70 return FilterNotifier.once("save"); | 74 return FilterNotifier.once("save"); |
71 } | 75 } |
72 | 76 |
| 77 function canonize(data) |
| 78 { |
| 79 let curSection = null; |
| 80 let sections = []; |
| 81 for (let line of (data + "\n[end]").split(/[\r\n]+/)) |
| 82 { |
| 83 if (/^\[.*\]$/.test(line)) |
| 84 { |
| 85 if (curSection) |
| 86 sections.push(curSection); |
| 87 |
| 88 curSection = {header: line, data: []}; |
| 89 } |
| 90 else if (curSection && /\S/.test(line)) |
| 91 curSection.data.push(line); |
| 92 } |
| 93 for (let section of sections) |
| 94 { |
| 95 section.key = section.header + " " + section.data[0]; |
| 96 section.data.sort(); |
| 97 } |
| 98 sections.sort((a, b) => |
| 99 { |
| 100 if (a.key < b.key) |
| 101 return -1; |
| 102 else if (a.key > b.key) |
| 103 return 1; |
| 104 return 0; |
| 105 }); |
| 106 return sections.map( |
| 107 section => [section.header].concat(section.data).join("\n") |
| 108 ).join("\n"); |
| 109 } |
| 110 |
73 function testReadWrite(test, withExternal) | 111 function testReadWrite(test, withExternal) |
74 { | 112 { |
75 let tempFile = IO.resolveFilePath("temp_patterns1.ini"); | |
76 let tempFile2 = IO.resolveFilePath("temp_patterns2.ini"); | |
77 | |
78 function canonize(data) | |
79 { | |
80 let curSection = null; | |
81 let sections = []; | |
82 for (let line of (data + "\n[end]").split(/[\r\n]+/)) | |
83 { | |
84 if (/^\[.*\]$/.test(line)) | |
85 { | |
86 if (curSection) | |
87 sections.push(curSection); | |
88 | |
89 curSection = {header: line, data: []}; | |
90 } | |
91 else if (curSection && /\S/.test(line)) | |
92 curSection.data.push(line); | |
93 } | |
94 for (let section of sections) | |
95 { | |
96 section.key = section.header + " " + section.data[0]; | |
97 section.data.sort(); | |
98 } | |
99 sections.sort((a, b) => | |
100 { | |
101 if (a.key < b.key) | |
102 return -1; | |
103 else if (a.key > b.key) | |
104 return 1; | |
105 return 0; | |
106 }); | |
107 return sections.map( | |
108 section => [section.header].concat(section.data).join("\n") | |
109 ).join("\n"); | |
110 } | |
111 | |
112 return testData.then(data => | 113 return testData.then(data => |
113 { | 114 { |
114 tempFile.contents = data; | 115 dataFile.contents = data; |
115 return loadFilters(tempFile); | 116 return loadFilters(); |
116 }).then(() => | 117 }).then(() => |
117 { | 118 { |
118 test.equal(FilterStorage.fileProperties.version, FilterStorage.formatVersion
, "File format version"); | 119 test.equal(FilterStorage.fileProperties.version, FilterStorage.formatVersion
, "File format version"); |
119 | 120 |
120 if (withExternal) | 121 if (withExternal) |
121 { | 122 { |
122 { | 123 { |
123 let subscription = new ExternalSubscription("~external~external subscrip
tion ID", "External subscription"); | 124 let subscription = new ExternalSubscription("~external~external subscrip
tion ID", "External subscription"); |
124 subscription.filters = [Filter.fromText("foo"), Filter.fromText("bar")]; | 125 subscription.filters = [Filter.fromText("foo"), Filter.fromText("bar")]; |
125 FilterStorage.addSubscription(subscription); | 126 FilterStorage.addSubscription(subscription); |
126 } | 127 } |
127 | 128 |
128 let externalSubscriptions = FilterStorage.subscriptions.filter(subscriptio
n => subscription instanceof ExternalSubscription); | 129 let externalSubscriptions = FilterStorage.subscriptions.filter(subscriptio
n => subscription instanceof ExternalSubscription); |
129 test.equal(externalSubscriptions.length, 1, "Number of external subscripti
ons after updateExternalSubscription"); | 130 test.equal(externalSubscriptions.length, 1, "Number of external subscripti
ons after updateExternalSubscription"); |
130 | 131 |
131 test.equal(externalSubscriptions[0].url, "~external~external subscription
ID", "ID of external subscription"); | 132 test.equal(externalSubscriptions[0].url, "~external~external subscription
ID", "ID of external subscription"); |
132 test.equal(externalSubscriptions[0].filters.length, 2, "Number of filters
in external subscription"); | 133 test.equal(externalSubscriptions[0].filters.length, 2, "Number of filters
in external subscription"); |
133 } | 134 } |
134 | 135 |
135 return saveFilters(tempFile2); | 136 return saveFilters(); |
136 }).then(() => testData).then(expected => | 137 }).then(() => testData).then(expected => |
137 { | 138 { |
138 test.equal(canonize(tempFile2.contents), canonize(expected), "Read/write res
ult"); | 139 test.equal(canonize(dataFile.contents), canonize(expected), "Read/write resu
lt"); |
139 }).catch(unexpectedError.bind(test)).then(() => test.done()); | 140 }).catch(unexpectedError.bind(test)).then(() => test.done()); |
140 } | 141 } |
141 | 142 |
142 exports.testReadAndSaveToFile = function(test) | 143 exports.testReadAndSaveToFile = function(test) |
143 { | 144 { |
144 testReadWrite(test, false); | 145 testReadWrite(test, false); |
145 }; | 146 }; |
146 | 147 |
147 exports.testReadAndSaveToFileWithExternalSubscription = function(test) | 148 exports.testReadAndSaveToFileWithExternalSubscription = function(test) |
148 { | 149 { |
149 testReadWrite(test, true); | 150 testReadWrite(test, true); |
150 }; | 151 }; |
151 | 152 |
152 exports.testLegacyGroups = {}; | 153 exports.testLegacyGroups = {}; |
153 | 154 |
154 for (let url of ["~wl~", "~fl~", "~eh~"]) | 155 for (let url of ["~wl~", "~fl~", "~eh~"]) |
155 { | 156 { |
156 exports.testLegacyGroups["read empty " + url] = function(test) | 157 exports.testLegacyGroups["read empty " + url] = function(test) |
157 { | 158 { |
158 let data = "[Subscription]\nurl=" + url; | 159 dataFile.contents = "[Subscription]\nurl=" + url; |
159 let tempFile = IO.resolveFilePath("temp_patterns1.ini"); | |
160 tempFile.contents = data; | |
161 | 160 |
162 loadFilters(tempFile, () => | 161 loadFilters(() => |
163 { | 162 { |
164 test.equal(FilterStorage.subscriptions.length, 0, "Number of filter subscr
iptions"); | 163 test.equal(FilterStorage.subscriptions.length, 0, "Number of filter subscr
iptions"); |
165 }).catch(unexpectedError.bind(test)).then(() => test.done()); | 164 }).catch(unexpectedError.bind(test)).then(() => test.done()); |
166 }; | 165 }; |
167 | 166 |
168 exports.testLegacyGroups["read non-empty " + url] = function(test) | 167 exports.testLegacyGroups["read non-empty " + url] = function(test) |
169 { | 168 { |
170 let data = "[Subscription]\nurl=" + url + "\n[Subscription filters]\nfoo"; | 169 dataFile.contents = "[Subscription]\nurl=" + url + "\n[Subscription filters]
\nfoo"; |
171 let tempFile = IO.resolveFilePath("temp_patterns1.ini"); | |
172 tempFile.contents = data; | |
173 | 170 |
174 loadFilters(tempFile).then(() => | 171 loadFilters().then(() => |
175 { | 172 { |
176 test.equal(FilterStorage.subscriptions.length, 1, "Number of filter subscr
iptions"); | 173 test.equal(FilterStorage.subscriptions.length, 1, "Number of filter subscr
iptions"); |
177 if (FilterStorage.subscriptions.length == 1) | 174 if (FilterStorage.subscriptions.length == 1) |
178 { | 175 { |
179 let subscription = FilterStorage.subscriptions[0]; | 176 let subscription = FilterStorage.subscriptions[0]; |
180 test.equal(subscription.url, url, "Subscription ID"); | 177 test.equal(subscription.url, url, "Subscription ID"); |
181 test.equal(subscription.title, null, "Subscription title"); | 178 test.equal(subscription.title, null, "Subscription title"); |
182 test.deepEqual(subscription.defaults, null, "Default types"); | 179 test.deepEqual(subscription.defaults, null, "Default types"); |
183 test.equal(subscription.filters.length, 1, "Number of subscription filte
rs"); | 180 test.equal(subscription.filters.length, 1, "Number of subscription filte
rs"); |
184 if (subscription.filters.length == 1) | 181 if (subscription.filters.length == 1) |
185 test.equal(subscription.filters[0].text, "foo", "First filter"); | 182 test.equal(subscription.filters[0].text, "foo", "First filter"); |
186 } | 183 } |
187 }).catch(unexpectedError.bind(test)).then(() => test.done()); | 184 }).catch(unexpectedError.bind(test)).then(() => test.done()); |
188 }; | 185 }; |
189 } | 186 } |
190 | 187 |
191 exports.testReadLegacyFilters = function(test) | 188 exports.testReadLegacyFilters = function(test) |
192 { | 189 { |
193 let data = "[Subscription]\nurl=~user~1234\ntitle=Foo\n[Subscription filters]\
n[User patterns]\nfoo\n\\[bar]\nfoo#bar"; | 190 dataFile.contents = "[Subscription]\nurl=~user~1234\ntitle=Foo\n[Subscription
filters]\n[User patterns]\nfoo\n\\[bar]\nfoo#bar"; |
194 let tempFile = IO.resolveFilePath("temp_patterns1.ini"); | |
195 tempFile.contents = data; | |
196 | 191 |
197 loadFilters(tempFile).then(() => | 192 loadFilters().then(() => |
198 { | 193 { |
199 test.equal(FilterStorage.subscriptions.length, 1, "Number of filter subscrip
tions"); | 194 test.equal(FilterStorage.subscriptions.length, 1, "Number of filter subscrip
tions"); |
200 if (FilterStorage.subscriptions.length == 1) | 195 if (FilterStorage.subscriptions.length == 1) |
201 { | 196 { |
202 let subscription = FilterStorage.subscriptions[0]; | 197 let subscription = FilterStorage.subscriptions[0]; |
203 test.equal(subscription.filters.length, 3, "Number of subscription filters
"); | 198 test.equal(subscription.filters.length, 3, "Number of subscription filters
"); |
204 if (subscription.filters.length == 3) | 199 if (subscription.filters.length == 3) |
205 { | 200 { |
206 test.equal(subscription.filters[0].text, "foo", "First filter"); | 201 test.equal(subscription.filters[0].text, "foo", "First filter"); |
207 test.equal(subscription.filters[1].text, "[bar]", "Second filter"); | 202 test.equal(subscription.filters[1].text, "[bar]", "Second filter"); |
208 test.equal(subscription.filters[2].text, "foo#bar", "Third filter"); | 203 test.equal(subscription.filters[2].text, "foo#bar", "Third filter"); |
209 } | 204 } |
210 } | 205 } |
211 }).catch(unexpectedError.bind(test)).then(() => test.done()); | 206 }).catch(unexpectedError.bind(test)).then(() => test.done()); |
212 }; | 207 }; |
213 | 208 |
| 209 exports.testImportExport = function(test) |
| 210 { |
| 211 testData.then(data => |
| 212 { |
| 213 let lines = data.split("\n"); |
| 214 if (lines.length && lines[lines.length - 1] == "") |
| 215 lines.pop(); |
| 216 |
| 217 let importer = FilterStorage.importData(); |
| 218 for (let line of lines) |
| 219 importer(line); |
| 220 importer(null); |
| 221 |
| 222 test.equal(FilterStorage.fileProperties.version, FilterStorage.formatVersion
, "File format version"); |
| 223 |
| 224 let exported = ""; |
| 225 for (let line of FilterStorage.exportData()) |
| 226 exported += line + "\n"; |
| 227 test.equal(canonize(exported), canonize(data), "Import/export result"); |
| 228 }).catch(unexpectedError.bind(test)).then(() => test.done()); |
| 229 }; |
| 230 |
214 exports.testSavingWithoutBackups = function(test) | 231 exports.testSavingWithoutBackups = function(test) |
215 { | 232 { |
216 Prefs.patternsbackups = 0; | 233 Prefs.patternsbackups = 0; |
217 Prefs.patternsbackupinterval = 24; | 234 Prefs.patternsbackupinterval = 24; |
218 | 235 |
219 let tempFile = IO.resolveFilePath("temp_patterns.ini"); | 236 saveFilters().then(() => |
220 Object.defineProperty(FilterStorage, "sourceFile", {get: () => tempFile.clone(
)}); | |
221 | |
222 saveFilters(null).then(() => | |
223 { | 237 { |
224 return saveFilters(null); | 238 return saveFilters(); |
225 }).then(() => | 239 }).then(() => |
226 { | 240 { |
227 let backupFile = tempFile.clone(); | 241 let backupFile = dataFile.clone(); |
228 backupFile.leafName = backupFile.leafName.replace(/\.ini$/, "-backup1.ini"); | 242 backupFile.leafName = backupFile.leafName.replace(/\.ini$/, "-backup1.ini"); |
229 test.ok(!backupFile.exists(), "Backup shouldn't be created"); | 243 test.ok(!backupFile.exists(), "Backup shouldn't be created"); |
230 }).catch(unexpectedError.bind(test)).then(() => test.done()); | 244 }).catch(unexpectedError.bind(test)).then(() => test.done()); |
231 }; | 245 }; |
232 | 246 |
233 exports.testSavingWithBackups = function(test) | 247 exports.testSavingWithBackups = function(test) |
234 { | 248 { |
235 Prefs.patternsbackups = 2; | 249 Prefs.patternsbackups = 2; |
236 Prefs.patternsbackupinterval = 24; | 250 Prefs.patternsbackupinterval = 24; |
237 | 251 |
238 let tempFile = IO.resolveFilePath("temp_patterns.ini"); | 252 let backupFile = dataFile.clone(); |
239 Object.defineProperty(FilterStorage, "sourceFile", {get: () => tempFile.clone(
)}); | |
240 | |
241 let backupFile = tempFile.clone(); | |
242 backupFile.leafName = backupFile.leafName.replace(/\.ini$/, "-backup1.ini"); | 253 backupFile.leafName = backupFile.leafName.replace(/\.ini$/, "-backup1.ini"); |
243 | 254 |
244 let backupFile2 = tempFile.clone(); | 255 let backupFile2 = dataFile.clone(); |
245 backupFile2.leafName = backupFile2.leafName.replace(/\.ini$/, "-backup2.ini"); | 256 backupFile2.leafName = backupFile2.leafName.replace(/\.ini$/, "-backup2.ini"); |
246 | 257 |
247 let backupFile3 = tempFile.clone(); | 258 let backupFile3 = dataFile.clone(); |
248 backupFile3.leafName = backupFile3.leafName.replace(/\.ini$/, "-backup3.ini"); | 259 backupFile3.leafName = backupFile3.leafName.replace(/\.ini$/, "-backup3.ini"); |
249 | 260 |
250 let oldModifiedTime; | 261 let oldModifiedTime; |
251 | 262 |
252 saveFilters(null).then(() => | 263 saveFilters().then(() => |
253 { | 264 { |
254 // Save again immediately | 265 // Save again immediately |
255 return saveFilters(null); | 266 return saveFilters(); |
256 }).then(() => | 267 }).then(() => |
257 { | 268 { |
258 test.ok(backupFile.exists(), "First backup created"); | 269 test.ok(backupFile.exists(), "First backup created"); |
259 | 270 |
260 backupFile.lastModifiedTime -= 10000; | 271 backupFile.lastModifiedTime -= 10000; |
261 oldModifiedTime = backupFile.lastModifiedTime; | 272 oldModifiedTime = backupFile.lastModifiedTime; |
262 return saveFilters(null); | 273 return saveFilters(); |
263 }).then(() => | 274 }).then(() => |
264 { | 275 { |
265 test.equal(backupFile.lastModifiedTime, oldModifiedTime, "Backup not overwri
tten if it is only 10 seconds old"); | 276 test.equal(backupFile.lastModifiedTime, oldModifiedTime, "Backup not overwri
tten if it is only 10 seconds old"); |
266 | 277 |
267 backupFile.lastModifiedTime -= 40 * 60 * 60 * 1000; | 278 backupFile.lastModifiedTime -= 40 * 60 * 60 * 1000; |
268 oldModifiedTime = backupFile.lastModifiedTime; | 279 oldModifiedTime = backupFile.lastModifiedTime; |
269 return saveFilters(null); | 280 return saveFilters(); |
270 }).then(() => | 281 }).then(() => |
271 { | 282 { |
272 test.notEqual(backupFile.lastModifiedTime, oldModifiedTime, "Backup overwrit
ten if it is 40 hours old"); | 283 test.notEqual(backupFile.lastModifiedTime, oldModifiedTime, "Backup overwrit
ten if it is 40 hours old"); |
273 | 284 |
274 test.ok(backupFile2.exists(), "Second backup created when first backup is ov
erwritten"); | 285 test.ok(backupFile2.exists(), "Second backup created when first backup is ov
erwritten"); |
275 | 286 |
276 backupFile.lastModifiedTime -= 20000; | 287 backupFile.lastModifiedTime -= 20000; |
277 oldModifiedTime = backupFile2.lastModifiedTime; | 288 oldModifiedTime = backupFile2.lastModifiedTime; |
278 return saveFilters(null); | 289 return saveFilters(); |
279 }).then(() => | 290 }).then(() => |
280 { | 291 { |
281 test.equal(backupFile2.lastModifiedTime, oldModifiedTime, "Second backup not
overwritten if first one is only 20 seconds old"); | 292 test.equal(backupFile2.lastModifiedTime, oldModifiedTime, "Second backup not
overwritten if first one is only 20 seconds old"); |
282 | 293 |
283 backupFile.lastModifiedTime -= 25 * 60 * 60 * 1000; | 294 backupFile.lastModifiedTime -= 25 * 60 * 60 * 1000; |
284 oldModifiedTime = backupFile2.lastModifiedTime; | 295 oldModifiedTime = backupFile2.lastModifiedTime; |
285 return saveFilters(null); | 296 return saveFilters(); |
286 }).then(() => | 297 }).then(() => |
287 { | 298 { |
288 test.notEqual(backupFile2.lastModifiedTime, oldModifiedTime, "Second backup
overwritten if first one is 25 hours old"); | 299 test.notEqual(backupFile2.lastModifiedTime, oldModifiedTime, "Second backup
overwritten if first one is 25 hours old"); |
289 | 300 |
290 test.ok(!backupFile3.exists(), "Third backup not created with patternsbackup
s = 2"); | 301 test.ok(!backupFile3.exists(), "Third backup not created with patternsbackup
s = 2"); |
291 }).catch(unexpectedError.bind(test)).then(() => test.done()); | 302 }).catch(unexpectedError.bind(test)).then(() => test.done()); |
292 }; | 303 }; |
| 304 |
| 305 exports.testRestoringBackup = function(test) |
| 306 { |
| 307 Prefs.patternsbackups = 2; |
| 308 Prefs.patternsbackupinterval = 24; |
| 309 |
| 310 saveFilters().then(() => |
| 311 { |
| 312 test.equal(FilterStorage.subscriptions.length, 1, "Initial subscription coun
t"); |
| 313 FilterStorage.removeSubscription(FilterStorage.subscriptions[0]); |
| 314 return saveFilters(); |
| 315 }).then(() => |
| 316 { |
| 317 return loadFilters(); |
| 318 }).then(() => |
| 319 { |
| 320 test.equal(FilterStorage.subscriptions.length, 0, "Subscription count after
removing subscriptions and reloading"); |
| 321 return FilterStorage.restoreBackup(1); |
| 322 }).then(() => |
| 323 { |
| 324 test.equal(FilterStorage.subscriptions.length, 1, "Subscription count after
restoring backup"); |
| 325 return loadFilters(); |
| 326 }).then(() => |
| 327 { |
| 328 test.equal(FilterStorage.subscriptions.length, 1, "Subscription count after
reloading"); |
| 329 }).catch(unexpectedError.bind(test)).then(() => test.done()); |
| 330 }; |
OLD | NEW |