| 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 const assert = require("assert"); |
| 20 const {createSandbox, unexpectedError} = require("./_common"); | 21 const {createSandbox, unexpectedError} = require("./_common"); |
| 21 | 22 |
| 22 let Filter = null; | 23 let Filter = null; |
| 23 let filterStorage = null; | 24 let filterStorage = null; |
| 24 let IO = null; | 25 let IO = null; |
| 25 let Prefs = null; | 26 let Prefs = null; |
| 26 let ExternalSubscription = null; | 27 let ExternalSubscription = null; |
| 27 let SpecialSubscription = null; | 28 let SpecialSubscription = null; |
| 28 | 29 |
| 29 exports.setUp = function(callback) | 30 describe("Filter Storage Read/Write", () => |
| 30 { | 31 { |
| 31 let sandboxedRequire = createSandbox(); | 32 beforeEach(() => |
| 32 ( | 33 { |
| 33 {Filter} = sandboxedRequire("../lib/filterClasses"), | 34 let sandboxedRequire = createSandbox(); |
| 34 {filterStorage} = sandboxedRequire("../lib/filterStorage"), | 35 ( |
| 35 {IO} = sandboxedRequire("./stub-modules/io"), | 36 {Filter} = sandboxedRequire("../lib/filterClasses"), |
| 36 {Prefs} = sandboxedRequire("./stub-modules/prefs"), | 37 {filterStorage} = sandboxedRequire("../lib/filterStorage"), |
| 37 {ExternalSubscription, SpecialSubscription} = sandboxedRequire("../lib/subsc
riptionClasses") | 38 {IO} = sandboxedRequire("./stub-modules/io"), |
| 38 ); | 39 {Prefs} = sandboxedRequire("./stub-modules/prefs"), |
| 39 | 40 {ExternalSubscription, SpecialSubscription} = sandboxedRequire("../lib/sub
scriptionClasses") |
| 40 filterStorage.addFilter(Filter.fromText("foobar")); | 41 ); |
| 41 callback(); | 42 |
| 42 }; | 43 filterStorage.addFilter(Filter.fromText("foobar")); |
| 43 | 44 }); |
| 44 let testData = new Promise((resolve, reject) => | 45 |
| 45 { | 46 let testData = new Promise((resolve, reject) => |
| 46 const fs = require("fs"); | 47 { |
| 47 const path = require("path"); | 48 const fs = require("fs"); |
| 48 let datapath = path.resolve(__dirname, "data", "patterns.ini"); | 49 const path = require("path"); |
| 49 | 50 let datapath = path.resolve(__dirname, "data", "patterns.ini"); |
| 50 fs.readFile(datapath, "utf-8", (error, data) => | 51 |
| 51 { | 52 fs.readFile(datapath, "utf-8", (error, data) => |
| 52 if (error) | 53 { |
| 53 reject(error); | 54 if (error) |
| 54 else | 55 reject(error); |
| 55 resolve(data.split(/[\r\n]+/)); | 56 else |
| 57 resolve(data.split(/[\r\n]+/)); |
| 58 }); |
| 59 }); |
| 60 |
| 61 function canonize(data) |
| 62 { |
| 63 let curSection = null; |
| 64 let sections = []; |
| 65 for (let line of data) |
| 66 { |
| 67 if (/^\[.*\]$/.test(line)) |
| 68 { |
| 69 if (curSection) |
| 70 sections.push(curSection); |
| 71 |
| 72 curSection = {header: line, data: []}; |
| 73 } |
| 74 else if (curSection && /\S/.test(line)) |
| 75 curSection.data.push(line); |
| 76 } |
| 77 if (curSection) |
| 78 sections.push(curSection); |
| 79 |
| 80 for (let section of sections) |
| 81 { |
| 82 section.key = section.header + " " + section.data[0]; |
| 83 section.data.sort(); |
| 84 } |
| 85 sections.sort((a, b) => |
| 86 { |
| 87 if (a.key < b.key) |
| 88 return -1; |
| 89 else if (a.key > b.key) |
| 90 return 1; |
| 91 return 0; |
| 92 }); |
| 93 return sections; |
| 94 } |
| 95 |
| 96 async function testReadWrite(withExternal, withEmptySpecial) |
| 97 { |
| 98 assert.ok(!filterStorage.initialized, "Uninitialized before the first load")
; |
| 99 |
| 100 try |
| 101 { |
| 102 let data = await testData; |
| 103 |
| 104 IO._setFileContents(filterStorage.sourceFile, data); |
| 105 await filterStorage.loadFromDisk(); |
| 106 |
| 107 assert.ok(filterStorage.initialized, "Initialize after the first load"); |
| 108 assert.equal(filterStorage.fileProperties.version, filterStorage.formatVer
sion, "File format version"); |
| 109 |
| 110 if (withExternal) |
| 111 { |
| 112 { |
| 113 let subscription = new ExternalSubscription("~external~external subscr
iption ID", "External subscription"); |
| 114 subscription.addFilter(Filter.fromText("foo")); |
| 115 subscription.addFilter(Filter.fromText("bar")); |
| 116 filterStorage.addSubscription(subscription); |
| 117 } |
| 118 |
| 119 let externalSubscriptions = [...filterStorage.subscriptions()].filter(su
bscription => subscription instanceof ExternalSubscription); |
| 120 assert.equal(externalSubscriptions.length, 1, "Number of external subscr
iptions after updateExternalSubscription"); |
| 121 |
| 122 assert.equal(externalSubscriptions[0].url, "~external~external subscript
ion ID", "ID of external subscription"); |
| 123 assert.equal(externalSubscriptions[0].filterCount, 2, "Number of filters
in external subscription"); |
| 124 } |
| 125 |
| 126 if (withEmptySpecial) |
| 127 { |
| 128 let specialSubscription = |
| 129 SpecialSubscription.createForFilter(Filter.fromText("!foo")); |
| 130 filterStorage.addSubscription(specialSubscription); |
| 131 |
| 132 filterStorage.removeFilter(Filter.fromText("!foo"), specialSubscription)
; |
| 133 |
| 134 assert.equal(specialSubscription.filterCount, 0, |
| 135 "No filters in special subscription"); |
| 136 assert.ok(new Set(filterStorage.subscriptions()).has(specialSubscription
), |
| 137 "Empty special subscription still in storage"); |
| 138 } |
| 139 |
| 140 await filterStorage.saveToDisk(); |
| 141 |
| 142 let expected = await testData; |
| 143 |
| 144 assert.deepEqual(canonize(IO._getFileContents(filterStorage.sourceFile)), |
| 145 canonize(expected), "Read/write result"); |
| 146 } |
| 147 catch (error) |
| 148 { |
| 149 unexpectedError.call(assert, error); |
| 150 } |
| 151 } |
| 152 |
| 153 describe("Read and Save", () => |
| 154 { |
| 155 it("to File", () => |
| 156 { |
| 157 testReadWrite(false); |
| 158 }); |
| 159 |
| 160 it("to file With External Subscription", () => |
| 161 { |
| 162 testReadWrite(true); |
| 163 }); |
| 164 |
| 165 it("to file With Empty Special", () => |
| 166 { |
| 167 testReadWrite(false, true); |
| 168 }); |
| 169 }); |
| 170 |
| 171 it("Import / Export", async() => |
| 172 { |
| 173 try |
| 174 { |
| 175 let lines = await testData; |
| 176 |
| 177 if (lines.length && lines[lines.length - 1] == "") |
| 178 lines.pop(); |
| 179 |
| 180 let importer = filterStorage.importData(); |
| 181 for (let line of lines) |
| 182 importer(line); |
| 183 importer(null); |
| 184 |
| 185 assert.equal(filterStorage.fileProperties.version, filterStorage.formatVer
sion, "File format version"); |
| 186 |
| 187 let exported = Array.from(filterStorage.exportData()); |
| 188 assert.deepEqual(canonize(exported), canonize(lines), "Import/export resul
t"); |
| 189 } |
| 190 catch (error) |
| 191 { |
| 192 unexpectedError.call(assert, error); |
| 193 } |
| 194 }); |
| 195 |
| 196 describe("Backups", () => |
| 197 { |
| 198 it("Saving Without", async() => |
| 199 { |
| 200 Prefs.patternsbackups = 0; |
| 201 Prefs.patternsbackupinterval = 24; |
| 202 |
| 203 try |
| 204 { |
| 205 await filterStorage.saveToDisk(); |
| 206 await filterStorage.saveToDisk(); |
| 207 |
| 208 assert.ok(!IO._getFileContents(filterStorage.getBackupName(1)), |
| 209 "Backup shouldn't be created"); |
| 210 } |
| 211 catch (error) |
| 212 { |
| 213 unexpectedError.call(assert, error); |
| 214 } |
| 215 }); |
| 216 |
| 217 it("Saving With", async() => |
| 218 { |
| 219 Prefs.patternsbackups = 2; |
| 220 Prefs.patternsbackupinterval = 24; |
| 221 |
| 222 let backupFile = filterStorage.getBackupName(1); |
| 223 let backupFile2 = filterStorage.getBackupName(2); |
| 224 let backupFile3 = filterStorage.getBackupName(3); |
| 225 |
| 226 let oldModifiedTime; |
| 227 |
| 228 try |
| 229 { |
| 230 await filterStorage.saveToDisk(); |
| 231 |
| 232 // Save again immediately |
| 233 await filterStorage.saveToDisk(); |
| 234 |
| 235 assert.ok(IO._getFileContents(backupFile), "First backup created"); |
| 236 |
| 237 oldModifiedTime = IO._getModifiedTime(backupFile) - 10000; |
| 238 IO._setModifiedTime(backupFile, oldModifiedTime); |
| 239 await filterStorage.saveToDisk(); |
| 240 |
| 241 assert.equal(IO._getModifiedTime(backupFile), oldModifiedTime, "Backup n
ot overwritten if it is only 10 seconds old"); |
| 242 |
| 243 oldModifiedTime -= 40 * 60 * 60 * 1000; |
| 244 IO._setModifiedTime(backupFile, oldModifiedTime); |
| 245 await filterStorage.saveToDisk(); |
| 246 |
| 247 assert.notEqual(IO._getModifiedTime(backupFile), oldModifiedTime, "Backu
p overwritten if it is 40 hours old"); |
| 248 |
| 249 assert.ok(IO._getFileContents(backupFile2), "Second backup created when
first backup is overwritten"); |
| 250 |
| 251 IO._setModifiedTime(backupFile, IO._getModifiedTime(backupFile) - 20000)
; |
| 252 oldModifiedTime = IO._getModifiedTime(backupFile2); |
| 253 await filterStorage.saveToDisk(); |
| 254 |
| 255 assert.equal(IO._getModifiedTime(backupFile2), oldModifiedTime, "Second
backup not overwritten if first one is only 20 seconds old"); |
| 256 |
| 257 IO._setModifiedTime(backupFile, IO._getModifiedTime(backupFile) - 25 * 6
0 * 60 * 1000); |
| 258 oldModifiedTime = IO._getModifiedTime(backupFile2); |
| 259 await filterStorage.saveToDisk(); |
| 260 |
| 261 assert.notEqual(IO._getModifiedTime(backupFile2), oldModifiedTime, "Seco
nd backup overwritten if first one is 25 hours old"); |
| 262 |
| 263 assert.ok(!IO._getFileContents(backupFile3), "Third backup not created w
ith patternsbackups = 2"); |
| 264 } |
| 265 catch (error) |
| 266 { |
| 267 unexpectedError.call(assert, error); |
| 268 } |
| 269 }); |
| 270 |
| 271 it("Restoring", async() => |
| 272 { |
| 273 Prefs.patternsbackups = 2; |
| 274 Prefs.patternsbackupinterval = 24; |
| 275 |
| 276 try |
| 277 { |
| 278 await filterStorage.saveToDisk(); |
| 279 |
| 280 assert.equal([...filterStorage.subscriptions()][0].filterCount, 1, "Init
ial filter count"); |
| 281 filterStorage.addFilter(Filter.fromText("barfoo")); |
| 282 assert.equal([...filterStorage.subscriptions()][0].filterCount, 2, "Filt
er count after adding a filter"); |
| 283 await filterStorage.saveToDisk(); |
| 284 |
| 285 await filterStorage.loadFromDisk(); |
| 286 |
| 287 assert.equal([...filterStorage.subscriptions()][0].filterCount, 2, "Filt
er count after adding filter and reloading"); |
| 288 await filterStorage.restoreBackup(1); |
| 289 |
| 290 assert.equal([...filterStorage.subscriptions()][0].filterCount, 1, "Filt
er count after restoring backup"); |
| 291 await filterStorage.loadFromDisk(); |
| 292 |
| 293 assert.equal([...filterStorage.subscriptions()][0].filterCount, 1, "Filt
er count after reloading"); |
| 294 } |
| 295 catch (error) |
| 296 { |
| 297 unexpectedError.call(assert, error); |
| 298 } |
| 299 }); |
| 56 }); | 300 }); |
| 57 }); | 301 }); |
| 58 | |
| 59 function canonize(data) | |
| 60 { | |
| 61 let curSection = null; | |
| 62 let sections = []; | |
| 63 for (let line of data) | |
| 64 { | |
| 65 if (/^\[.*\]$/.test(line)) | |
| 66 { | |
| 67 if (curSection) | |
| 68 sections.push(curSection); | |
| 69 | |
| 70 curSection = {header: line, data: []}; | |
| 71 } | |
| 72 else if (curSection && /\S/.test(line)) | |
| 73 curSection.data.push(line); | |
| 74 } | |
| 75 if (curSection) | |
| 76 sections.push(curSection); | |
| 77 | |
| 78 for (let section of sections) | |
| 79 { | |
| 80 section.key = section.header + " " + section.data[0]; | |
| 81 section.data.sort(); | |
| 82 } | |
| 83 sections.sort((a, b) => | |
| 84 { | |
| 85 if (a.key < b.key) | |
| 86 return -1; | |
| 87 else if (a.key > b.key) | |
| 88 return 1; | |
| 89 return 0; | |
| 90 }); | |
| 91 return sections; | |
| 92 } | |
| 93 | |
| 94 async function testReadWrite(test, withExternal, withEmptySpecial) | |
| 95 { | |
| 96 test.ok(!filterStorage.initialized, "Uninitialized before the first load"); | |
| 97 | |
| 98 try | |
| 99 { | |
| 100 let data = await testData; | |
| 101 | |
| 102 IO._setFileContents(filterStorage.sourceFile, data); | |
| 103 await filterStorage.loadFromDisk(); | |
| 104 | |
| 105 test.ok(filterStorage.initialized, "Initialize after the first load"); | |
| 106 test.equal(filterStorage.fileProperties.version, filterStorage.formatVersion
, "File format version"); | |
| 107 | |
| 108 if (withExternal) | |
| 109 { | |
| 110 { | |
| 111 let subscription = new ExternalSubscription("~external~external subscrip
tion ID", "External subscription"); | |
| 112 subscription.addFilter(Filter.fromText("foo")); | |
| 113 subscription.addFilter(Filter.fromText("bar")); | |
| 114 filterStorage.addSubscription(subscription); | |
| 115 } | |
| 116 | |
| 117 let externalSubscriptions = [...filterStorage.subscriptions()].filter(subs
cription => subscription instanceof ExternalSubscription); | |
| 118 test.equal(externalSubscriptions.length, 1, "Number of external subscripti
ons after updateExternalSubscription"); | |
| 119 | |
| 120 test.equal(externalSubscriptions[0].url, "~external~external subscription
ID", "ID of external subscription"); | |
| 121 test.equal(externalSubscriptions[0].filterCount, 2, "Number of filters in
external subscription"); | |
| 122 } | |
| 123 | |
| 124 if (withEmptySpecial) | |
| 125 { | |
| 126 let specialSubscription = | |
| 127 SpecialSubscription.createForFilter(Filter.fromText("!foo")); | |
| 128 filterStorage.addSubscription(specialSubscription); | |
| 129 | |
| 130 filterStorage.removeFilter(Filter.fromText("!foo"), specialSubscription); | |
| 131 | |
| 132 test.equal(specialSubscription.filterCount, 0, | |
| 133 "No filters in special subscription"); | |
| 134 test.ok(new Set(filterStorage.subscriptions()).has(specialSubscription), | |
| 135 "Empty special subscription still in storage"); | |
| 136 } | |
| 137 | |
| 138 await filterStorage.saveToDisk(); | |
| 139 | |
| 140 let expected = await testData; | |
| 141 | |
| 142 test.deepEqual(canonize(IO._getFileContents(filterStorage.sourceFile)), | |
| 143 canonize(expected), "Read/write result"); | |
| 144 } | |
| 145 catch (error) | |
| 146 { | |
| 147 unexpectedError.call(test, error); | |
| 148 } | |
| 149 | |
| 150 test.done(); | |
| 151 } | |
| 152 | |
| 153 exports.testReadAndSaveToFile = function(test) | |
| 154 { | |
| 155 testReadWrite(test, false); | |
| 156 }; | |
| 157 | |
| 158 exports.testReadAndSaveToFileWithExternalSubscription = function(test) | |
| 159 { | |
| 160 testReadWrite(test, true); | |
| 161 }; | |
| 162 | |
| 163 exports.testReadAndSaveToFileWithEmptySpecial = function(test) | |
| 164 { | |
| 165 testReadWrite(test, false, true); | |
| 166 }; | |
| 167 | |
| 168 exports.testImportExport = async function(test) | |
| 169 { | |
| 170 try | |
| 171 { | |
| 172 let lines = await testData; | |
| 173 | |
| 174 if (lines.length && lines[lines.length - 1] == "") | |
| 175 lines.pop(); | |
| 176 | |
| 177 let importer = filterStorage.importData(); | |
| 178 for (let line of lines) | |
| 179 importer(line); | |
| 180 importer(null); | |
| 181 | |
| 182 test.equal(filterStorage.fileProperties.version, filterStorage.formatVersion
, "File format version"); | |
| 183 | |
| 184 let exported = Array.from(filterStorage.exportData()); | |
| 185 test.deepEqual(canonize(exported), canonize(lines), "Import/export result"); | |
| 186 } | |
| 187 catch (error) | |
| 188 { | |
| 189 unexpectedError.call(test, error); | |
| 190 } | |
| 191 | |
| 192 test.done(); | |
| 193 }; | |
| 194 | |
| 195 exports.testSavingWithoutBackups = async function(test) | |
| 196 { | |
| 197 Prefs.patternsbackups = 0; | |
| 198 Prefs.patternsbackupinterval = 24; | |
| 199 | |
| 200 try | |
| 201 { | |
| 202 await filterStorage.saveToDisk(); | |
| 203 await filterStorage.saveToDisk(); | |
| 204 | |
| 205 test.ok(!IO._getFileContents(filterStorage.getBackupName(1)), | |
| 206 "Backup shouldn't be created"); | |
| 207 } | |
| 208 catch (error) | |
| 209 { | |
| 210 unexpectedError.call(test, error); | |
| 211 } | |
| 212 | |
| 213 test.done(); | |
| 214 }; | |
| 215 | |
| 216 exports.testSavingWithBackups = async function(test) | |
| 217 { | |
| 218 Prefs.patternsbackups = 2; | |
| 219 Prefs.patternsbackupinterval = 24; | |
| 220 | |
| 221 let backupFile = filterStorage.getBackupName(1); | |
| 222 let backupFile2 = filterStorage.getBackupName(2); | |
| 223 let backupFile3 = filterStorage.getBackupName(3); | |
| 224 | |
| 225 let oldModifiedTime; | |
| 226 | |
| 227 try | |
| 228 { | |
| 229 await filterStorage.saveToDisk(); | |
| 230 | |
| 231 // Save again immediately | |
| 232 await filterStorage.saveToDisk(); | |
| 233 | |
| 234 test.ok(IO._getFileContents(backupFile), "First backup created"); | |
| 235 | |
| 236 oldModifiedTime = IO._getModifiedTime(backupFile) - 10000; | |
| 237 IO._setModifiedTime(backupFile, oldModifiedTime); | |
| 238 await filterStorage.saveToDisk(); | |
| 239 | |
| 240 test.equal(IO._getModifiedTime(backupFile), oldModifiedTime, "Backup not ove
rwritten if it is only 10 seconds old"); | |
| 241 | |
| 242 oldModifiedTime -= 40 * 60 * 60 * 1000; | |
| 243 IO._setModifiedTime(backupFile, oldModifiedTime); | |
| 244 await filterStorage.saveToDisk(); | |
| 245 | |
| 246 test.notEqual(IO._getModifiedTime(backupFile), oldModifiedTime, "Backup over
written if it is 40 hours old"); | |
| 247 | |
| 248 test.ok(IO._getFileContents(backupFile2), "Second backup created when first
backup is overwritten"); | |
| 249 | |
| 250 IO._setModifiedTime(backupFile, IO._getModifiedTime(backupFile) - 20000); | |
| 251 oldModifiedTime = IO._getModifiedTime(backupFile2); | |
| 252 await filterStorage.saveToDisk(); | |
| 253 | |
| 254 test.equal(IO._getModifiedTime(backupFile2), oldModifiedTime, "Second backup
not overwritten if first one is only 20 seconds old"); | |
| 255 | |
| 256 IO._setModifiedTime(backupFile, IO._getModifiedTime(backupFile) - 25 * 60 *
60 * 1000); | |
| 257 oldModifiedTime = IO._getModifiedTime(backupFile2); | |
| 258 await filterStorage.saveToDisk(); | |
| 259 | |
| 260 test.notEqual(IO._getModifiedTime(backupFile2), oldModifiedTime, "Second bac
kup overwritten if first one is 25 hours old"); | |
| 261 | |
| 262 test.ok(!IO._getFileContents(backupFile3), "Third backup not created with pa
tternsbackups = 2"); | |
| 263 } | |
| 264 catch (error) | |
| 265 { | |
| 266 unexpectedError.call(test, error); | |
| 267 } | |
| 268 | |
| 269 test.done(); | |
| 270 }; | |
| 271 | |
| 272 exports.testRestoringBackup = async function(test) | |
| 273 { | |
| 274 Prefs.patternsbackups = 2; | |
| 275 Prefs.patternsbackupinterval = 24; | |
| 276 | |
| 277 try | |
| 278 { | |
| 279 await filterStorage.saveToDisk(); | |
| 280 | |
| 281 test.equal([...filterStorage.subscriptions()][0].filterCount, 1, "Initial fi
lter count"); | |
| 282 filterStorage.addFilter(Filter.fromText("barfoo")); | |
| 283 test.equal([...filterStorage.subscriptions()][0].filterCount, 2, "Filter cou
nt after adding a filter"); | |
| 284 await filterStorage.saveToDisk(); | |
| 285 | |
| 286 await filterStorage.loadFromDisk(); | |
| 287 | |
| 288 test.equal([...filterStorage.subscriptions()][0].filterCount, 2, "Filter cou
nt after adding filter and reloading"); | |
| 289 await filterStorage.restoreBackup(1); | |
| 290 | |
| 291 test.equal([...filterStorage.subscriptions()][0].filterCount, 1, "Filter cou
nt after restoring backup"); | |
| 292 await filterStorage.loadFromDisk(); | |
| 293 | |
| 294 test.equal([...filterStorage.subscriptions()][0].filterCount, 1, "Filter cou
nt after reloading"); | |
| 295 } | |
| 296 catch (error) | |
| 297 { | |
| 298 unexpectedError.call(test, error); | |
| 299 } | |
| 300 | |
| 301 test.done(); | |
| 302 }; | |
| OLD | NEW |