Wed, 31 Dec 2014 06:09:35 +0100
Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.
michael@0 | 1 | /* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
michael@0 | 2 | /* vim:set ts=2 sw=2 sts=2 et: */ |
michael@0 | 3 | /* This Source Code Form is subject to the terms of the Mozilla Public |
michael@0 | 4 | * License, v. 2.0. If a copy of the MPL was not distributed with this |
michael@0 | 5 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
michael@0 | 6 | |
michael@0 | 7 | /** |
michael@0 | 8 | * Test preventive maintenance |
michael@0 | 9 | * For every maintenance query create an uncoherent db and check that we take |
michael@0 | 10 | * correct fix steps, without polluting valid data. |
michael@0 | 11 | */ |
michael@0 | 12 | |
michael@0 | 13 | // Include PlacesDBUtils module |
michael@0 | 14 | Components.utils.import("resource://gre/modules/PlacesDBUtils.jsm"); |
michael@0 | 15 | |
michael@0 | 16 | const FINISHED_MAINTENANCE_NOTIFICATION_TOPIC = "places-maintenance-finished"; |
michael@0 | 17 | |
michael@0 | 18 | // Get services and database connection |
michael@0 | 19 | let hs = PlacesUtils.history; |
michael@0 | 20 | let bs = PlacesUtils.bookmarks; |
michael@0 | 21 | let ts = PlacesUtils.tagging; |
michael@0 | 22 | let as = PlacesUtils.annotations; |
michael@0 | 23 | let fs = PlacesUtils.favicons; |
michael@0 | 24 | |
michael@0 | 25 | let mDBConn = hs.QueryInterface(Ci.nsPIPlacesDatabase).DBConnection; |
michael@0 | 26 | |
michael@0 | 27 | //------------------------------------------------------------------------------ |
michael@0 | 28 | // Helpers |
michael@0 | 29 | |
michael@0 | 30 | let defaultBookmarksMaxId = 0; |
michael@0 | 31 | function cleanDatabase() { |
michael@0 | 32 | mDBConn.executeSimpleSQL("DELETE FROM moz_places"); |
michael@0 | 33 | mDBConn.executeSimpleSQL("DELETE FROM moz_historyvisits"); |
michael@0 | 34 | mDBConn.executeSimpleSQL("DELETE FROM moz_anno_attributes"); |
michael@0 | 35 | mDBConn.executeSimpleSQL("DELETE FROM moz_annos"); |
michael@0 | 36 | mDBConn.executeSimpleSQL("DELETE FROM moz_items_annos"); |
michael@0 | 37 | mDBConn.executeSimpleSQL("DELETE FROM moz_inputhistory"); |
michael@0 | 38 | mDBConn.executeSimpleSQL("DELETE FROM moz_keywords"); |
michael@0 | 39 | mDBConn.executeSimpleSQL("DELETE FROM moz_favicons"); |
michael@0 | 40 | mDBConn.executeSimpleSQL("DELETE FROM moz_bookmarks WHERE id > " + defaultBookmarksMaxId); |
michael@0 | 41 | } |
michael@0 | 42 | |
michael@0 | 43 | function addPlace(aUrl, aFavicon) { |
michael@0 | 44 | let stmt = mDBConn.createStatement( |
michael@0 | 45 | "INSERT INTO moz_places (url, favicon_id) VALUES (:url, :favicon)"); |
michael@0 | 46 | stmt.params["url"] = aUrl || "http://www.mozilla.org"; |
michael@0 | 47 | stmt.params["favicon"] = aFavicon || null; |
michael@0 | 48 | stmt.execute(); |
michael@0 | 49 | stmt.finalize(); |
michael@0 | 50 | return mDBConn.lastInsertRowID; |
michael@0 | 51 | } |
michael@0 | 52 | |
michael@0 | 53 | function addBookmark(aPlaceId, aType, aParent, aKeywordId, aFolderType, aTitle) { |
michael@0 | 54 | let stmt = mDBConn.createStatement( |
michael@0 | 55 | "INSERT INTO moz_bookmarks (fk, type, parent, keyword_id, folder_type, " |
michael@0 | 56 | + "title, guid) " |
michael@0 | 57 | + "VALUES (:place_id, :type, :parent, :keyword_id, :folder_type, :title, " |
michael@0 | 58 | + "GENERATE_GUID())"); |
michael@0 | 59 | stmt.params["place_id"] = aPlaceId || null; |
michael@0 | 60 | stmt.params["type"] = aType || bs.TYPE_BOOKMARK; |
michael@0 | 61 | stmt.params["parent"] = aParent || bs.unfiledBookmarksFolder; |
michael@0 | 62 | stmt.params["keyword_id"] = aKeywordId || null; |
michael@0 | 63 | stmt.params["folder_type"] = aFolderType || null; |
michael@0 | 64 | stmt.params["title"] = typeof(aTitle) == "string" ? aTitle : null; |
michael@0 | 65 | stmt.execute(); |
michael@0 | 66 | stmt.finalize(); |
michael@0 | 67 | return mDBConn.lastInsertRowID; |
michael@0 | 68 | } |
michael@0 | 69 | |
michael@0 | 70 | //------------------------------------------------------------------------------ |
michael@0 | 71 | // Tests |
michael@0 | 72 | |
michael@0 | 73 | let tests = []; |
michael@0 | 74 | |
michael@0 | 75 | //------------------------------------------------------------------------------ |
michael@0 | 76 | |
michael@0 | 77 | tests.push({ |
michael@0 | 78 | name: "A.1", |
michael@0 | 79 | desc: "Remove obsolete annotations from moz_annos", |
michael@0 | 80 | |
michael@0 | 81 | _obsoleteWeaveAttribute: "weave/test", |
michael@0 | 82 | _placeId: null, |
michael@0 | 83 | |
michael@0 | 84 | setup: function() { |
michael@0 | 85 | // Add a place to ensure place_id = 1 is valid. |
michael@0 | 86 | this._placeId = addPlace(); |
michael@0 | 87 | // Add an obsolete attribute. |
michael@0 | 88 | let stmt = mDBConn.createStatement( |
michael@0 | 89 | "INSERT INTO moz_anno_attributes (name) VALUES (:anno)" |
michael@0 | 90 | ); |
michael@0 | 91 | stmt.params['anno'] = this._obsoleteWeaveAttribute; |
michael@0 | 92 | stmt.execute(); |
michael@0 | 93 | stmt.finalize(); |
michael@0 | 94 | stmt = mDBConn.createStatement( |
michael@0 | 95 | "INSERT INTO moz_annos (place_id, anno_attribute_id) " |
michael@0 | 96 | + "VALUES (:place_id, " |
michael@0 | 97 | + "(SELECT id FROM moz_anno_attributes WHERE name = :anno)" |
michael@0 | 98 | + ")" |
michael@0 | 99 | ); |
michael@0 | 100 | stmt.params['place_id'] = this._placeId; |
michael@0 | 101 | stmt.params['anno'] = this._obsoleteWeaveAttribute; |
michael@0 | 102 | stmt.execute(); |
michael@0 | 103 | stmt.finalize(); |
michael@0 | 104 | }, |
michael@0 | 105 | |
michael@0 | 106 | check: function() { |
michael@0 | 107 | // Check that the obsolete annotation has been removed. |
michael@0 | 108 | let stmt = mDBConn.createStatement( |
michael@0 | 109 | "SELECT id FROM moz_anno_attributes WHERE name = :anno" |
michael@0 | 110 | ); |
michael@0 | 111 | stmt.params['anno'] = this._obsoleteWeaveAttribute; |
michael@0 | 112 | do_check_false(stmt.executeStep()); |
michael@0 | 113 | stmt.finalize(); |
michael@0 | 114 | } |
michael@0 | 115 | }); |
michael@0 | 116 | |
michael@0 | 117 | tests.push({ |
michael@0 | 118 | name: "A.2", |
michael@0 | 119 | desc: "Remove obsolete annotations from moz_items_annos", |
michael@0 | 120 | |
michael@0 | 121 | _obsoleteSyncAttribute: "sync/children", |
michael@0 | 122 | _obsoleteGuidAttribute: "placesInternal/GUID", |
michael@0 | 123 | _obsoleteWeaveAttribute: "weave/test", |
michael@0 | 124 | _placeId: null, |
michael@0 | 125 | _bookmarkId: null, |
michael@0 | 126 | |
michael@0 | 127 | setup: function() { |
michael@0 | 128 | // Add a place to ensure place_id = 1 is valid. |
michael@0 | 129 | this._placeId = addPlace(); |
michael@0 | 130 | // Add a bookmark. |
michael@0 | 131 | this._bookmarkId = addBookmark(this._placeId); |
michael@0 | 132 | // Add an obsolete attribute. |
michael@0 | 133 | let stmt = mDBConn.createStatement( |
michael@0 | 134 | "INSERT INTO moz_anno_attributes (name) " |
michael@0 | 135 | + "VALUES (:anno1), (:anno2), (:anno3)" |
michael@0 | 136 | ); |
michael@0 | 137 | stmt.params['anno1'] = this._obsoleteSyncAttribute; |
michael@0 | 138 | stmt.params['anno2'] = this._obsoleteGuidAttribute; |
michael@0 | 139 | stmt.params['anno3'] = this._obsoleteWeaveAttribute; |
michael@0 | 140 | stmt.execute(); |
michael@0 | 141 | stmt.finalize(); |
michael@0 | 142 | stmt = mDBConn.createStatement( |
michael@0 | 143 | "INSERT INTO moz_items_annos (item_id, anno_attribute_id) " |
michael@0 | 144 | + "SELECT :item_id, id " |
michael@0 | 145 | + "FROM moz_anno_attributes " |
michael@0 | 146 | + "WHERE name IN (:anno1, :anno2, :anno3)" |
michael@0 | 147 | ); |
michael@0 | 148 | stmt.params['item_id'] = this._bookmarkId; |
michael@0 | 149 | stmt.params['anno1'] = this._obsoleteSyncAttribute; |
michael@0 | 150 | stmt.params['anno2'] = this._obsoleteGuidAttribute; |
michael@0 | 151 | stmt.params['anno3'] = this._obsoleteWeaveAttribute; |
michael@0 | 152 | stmt.execute(); |
michael@0 | 153 | stmt.finalize(); |
michael@0 | 154 | }, |
michael@0 | 155 | |
michael@0 | 156 | check: function() { |
michael@0 | 157 | // Check that the obsolete annotations have been removed. |
michael@0 | 158 | let stmt = mDBConn.createStatement( |
michael@0 | 159 | "SELECT id FROM moz_anno_attributes " |
michael@0 | 160 | + "WHERE name IN (:anno1, :anno2, :anno3)" |
michael@0 | 161 | ); |
michael@0 | 162 | stmt.params['anno1'] = this._obsoleteSyncAttribute; |
michael@0 | 163 | stmt.params['anno2'] = this._obsoleteGuidAttribute; |
michael@0 | 164 | stmt.params['anno3'] = this._obsoleteWeaveAttribute; |
michael@0 | 165 | do_check_false(stmt.executeStep()); |
michael@0 | 166 | stmt.finalize(); |
michael@0 | 167 | } |
michael@0 | 168 | }); |
michael@0 | 169 | |
michael@0 | 170 | tests.push({ |
michael@0 | 171 | name: "A.3", |
michael@0 | 172 | desc: "Remove unused attributes", |
michael@0 | 173 | |
michael@0 | 174 | _usedPageAttribute: "usedPage", |
michael@0 | 175 | _usedItemAttribute: "usedItem", |
michael@0 | 176 | _unusedAttribute: "unused", |
michael@0 | 177 | _placeId: null, |
michael@0 | 178 | _bookmarkId: null, |
michael@0 | 179 | |
michael@0 | 180 | setup: function() { |
michael@0 | 181 | // Add a place to ensure place_id = 1 is valid |
michael@0 | 182 | this._placeId = addPlace(); |
michael@0 | 183 | // add a bookmark |
michael@0 | 184 | this._bookmarkId = addBookmark(this._placeId); |
michael@0 | 185 | // Add a used attribute and an unused one. |
michael@0 | 186 | let stmt = mDBConn.createStatement("INSERT INTO moz_anno_attributes (name) VALUES (:anno)"); |
michael@0 | 187 | stmt.params['anno'] = this._usedPageAttribute; |
michael@0 | 188 | stmt.execute(); |
michael@0 | 189 | stmt.reset(); |
michael@0 | 190 | stmt.params['anno'] = this._usedItemAttribute; |
michael@0 | 191 | stmt.execute(); |
michael@0 | 192 | stmt.reset(); |
michael@0 | 193 | stmt.params['anno'] = this._unusedAttribute; |
michael@0 | 194 | stmt.execute(); |
michael@0 | 195 | stmt.finalize(); |
michael@0 | 196 | |
michael@0 | 197 | stmt = mDBConn.createStatement("INSERT INTO moz_annos (place_id, anno_attribute_id) VALUES(:place_id, (SELECT id FROM moz_anno_attributes WHERE name = :anno))"); |
michael@0 | 198 | stmt.params['place_id'] = this._placeId; |
michael@0 | 199 | stmt.params['anno'] = this._usedPageAttribute; |
michael@0 | 200 | stmt.execute(); |
michael@0 | 201 | stmt.finalize(); |
michael@0 | 202 | stmt = mDBConn.createStatement("INSERT INTO moz_items_annos (item_id, anno_attribute_id) VALUES(:item_id, (SELECT id FROM moz_anno_attributes WHERE name = :anno))"); |
michael@0 | 203 | stmt.params['item_id'] = this._bookmarkId; |
michael@0 | 204 | stmt.params['anno'] = this._usedItemAttribute; |
michael@0 | 205 | stmt.execute(); |
michael@0 | 206 | stmt.finalize(); |
michael@0 | 207 | }, |
michael@0 | 208 | |
michael@0 | 209 | check: function() { |
michael@0 | 210 | // Check that used attributes are still there |
michael@0 | 211 | let stmt = mDBConn.createStatement("SELECT id FROM moz_anno_attributes WHERE name = :anno"); |
michael@0 | 212 | stmt.params['anno'] = this._usedPageAttribute; |
michael@0 | 213 | do_check_true(stmt.executeStep()); |
michael@0 | 214 | stmt.reset(); |
michael@0 | 215 | stmt.params['anno'] = this._usedItemAttribute; |
michael@0 | 216 | do_check_true(stmt.executeStep()); |
michael@0 | 217 | stmt.reset(); |
michael@0 | 218 | // Check that unused attribute has been removed |
michael@0 | 219 | stmt.params['anno'] = this._unusedAttribute; |
michael@0 | 220 | do_check_false(stmt.executeStep()); |
michael@0 | 221 | stmt.finalize(); |
michael@0 | 222 | } |
michael@0 | 223 | }); |
michael@0 | 224 | |
michael@0 | 225 | //------------------------------------------------------------------------------ |
michael@0 | 226 | |
michael@0 | 227 | tests.push({ |
michael@0 | 228 | name: "B.1", |
michael@0 | 229 | desc: "Remove annotations with an invalid attribute", |
michael@0 | 230 | |
michael@0 | 231 | _usedPageAttribute: "usedPage", |
michael@0 | 232 | _placeId: null, |
michael@0 | 233 | |
michael@0 | 234 | setup: function() { |
michael@0 | 235 | // Add a place to ensure place_id = 1 is valid |
michael@0 | 236 | this._placeId = addPlace(); |
michael@0 | 237 | // Add a used attribute. |
michael@0 | 238 | let stmt = mDBConn.createStatement("INSERT INTO moz_anno_attributes (name) VALUES (:anno)"); |
michael@0 | 239 | stmt.params['anno'] = this._usedPageAttribute; |
michael@0 | 240 | stmt.execute(); |
michael@0 | 241 | stmt.finalize(); |
michael@0 | 242 | stmt = mDBConn.createStatement("INSERT INTO moz_annos (place_id, anno_attribute_id) VALUES(:place_id, (SELECT id FROM moz_anno_attributes WHERE name = :anno))"); |
michael@0 | 243 | stmt.params['place_id'] = this._placeId; |
michael@0 | 244 | stmt.params['anno'] = this._usedPageAttribute; |
michael@0 | 245 | stmt.execute(); |
michael@0 | 246 | stmt.finalize(); |
michael@0 | 247 | // Add an annotation with a nonexistent attribute |
michael@0 | 248 | stmt = mDBConn.createStatement("INSERT INTO moz_annos (place_id, anno_attribute_id) VALUES(:place_id, 1337)"); |
michael@0 | 249 | stmt.params['place_id'] = this._placeId; |
michael@0 | 250 | stmt.execute(); |
michael@0 | 251 | stmt.finalize(); |
michael@0 | 252 | }, |
michael@0 | 253 | |
michael@0 | 254 | check: function() { |
michael@0 | 255 | // Check that used attribute is still there |
michael@0 | 256 | let stmt = mDBConn.createStatement("SELECT id FROM moz_anno_attributes WHERE name = :anno"); |
michael@0 | 257 | stmt.params['anno'] = this._usedPageAttribute; |
michael@0 | 258 | do_check_true(stmt.executeStep()); |
michael@0 | 259 | stmt.finalize(); |
michael@0 | 260 | // check that annotation with valid attribute is still there |
michael@0 | 261 | stmt = mDBConn.createStatement("SELECT id FROM moz_annos WHERE anno_attribute_id = (SELECT id FROM moz_anno_attributes WHERE name = :anno)"); |
michael@0 | 262 | stmt.params['anno'] = this._usedPageAttribute; |
michael@0 | 263 | do_check_true(stmt.executeStep()); |
michael@0 | 264 | stmt.finalize(); |
michael@0 | 265 | // Check that annotation with bogus attribute has been removed |
michael@0 | 266 | stmt = mDBConn.createStatement("SELECT id FROM moz_annos WHERE anno_attribute_id = 1337"); |
michael@0 | 267 | do_check_false(stmt.executeStep()); |
michael@0 | 268 | stmt.finalize(); |
michael@0 | 269 | } |
michael@0 | 270 | }); |
michael@0 | 271 | |
michael@0 | 272 | //------------------------------------------------------------------------------ |
michael@0 | 273 | |
michael@0 | 274 | tests.push({ |
michael@0 | 275 | name: "B.2", |
michael@0 | 276 | desc: "Remove orphan page annotations", |
michael@0 | 277 | |
michael@0 | 278 | _usedPageAttribute: "usedPage", |
michael@0 | 279 | _placeId: null, |
michael@0 | 280 | |
michael@0 | 281 | setup: function() { |
michael@0 | 282 | // Add a place to ensure place_id = 1 is valid |
michael@0 | 283 | this._placeId = addPlace(); |
michael@0 | 284 | // Add a used attribute. |
michael@0 | 285 | let stmt = mDBConn.createStatement("INSERT INTO moz_anno_attributes (name) VALUES (:anno)"); |
michael@0 | 286 | stmt.params['anno'] = this._usedPageAttribute; |
michael@0 | 287 | stmt.execute(); |
michael@0 | 288 | stmt.finalize(); |
michael@0 | 289 | stmt = mDBConn.createStatement("INSERT INTO moz_annos (place_id, anno_attribute_id) VALUES(:place_id, (SELECT id FROM moz_anno_attributes WHERE name = :anno))"); |
michael@0 | 290 | stmt.params['place_id'] = this._placeId; |
michael@0 | 291 | stmt.params['anno'] = this._usedPageAttribute; |
michael@0 | 292 | stmt.execute(); |
michael@0 | 293 | stmt.reset(); |
michael@0 | 294 | // Add an annotation to a nonexistent page |
michael@0 | 295 | stmt.params['place_id'] = 1337; |
michael@0 | 296 | stmt.params['anno'] = this._usedPageAttribute; |
michael@0 | 297 | stmt.execute(); |
michael@0 | 298 | stmt.finalize(); |
michael@0 | 299 | }, |
michael@0 | 300 | |
michael@0 | 301 | check: function() { |
michael@0 | 302 | // Check that used attribute is still there |
michael@0 | 303 | let stmt = mDBConn.createStatement("SELECT id FROM moz_anno_attributes WHERE name = :anno"); |
michael@0 | 304 | stmt.params['anno'] = this._usedPageAttribute; |
michael@0 | 305 | do_check_true(stmt.executeStep()); |
michael@0 | 306 | stmt.finalize(); |
michael@0 | 307 | // check that annotation with valid attribute is still there |
michael@0 | 308 | stmt = mDBConn.createStatement("SELECT id FROM moz_annos WHERE anno_attribute_id = (SELECT id FROM moz_anno_attributes WHERE name = :anno)"); |
michael@0 | 309 | stmt.params['anno'] = this._usedPageAttribute; |
michael@0 | 310 | do_check_true(stmt.executeStep()); |
michael@0 | 311 | stmt.finalize(); |
michael@0 | 312 | // Check that an annotation to a nonexistent page has been removed |
michael@0 | 313 | stmt = mDBConn.createStatement("SELECT id FROM moz_annos WHERE place_id = 1337"); |
michael@0 | 314 | do_check_false(stmt.executeStep()); |
michael@0 | 315 | stmt.finalize(); |
michael@0 | 316 | } |
michael@0 | 317 | }); |
michael@0 | 318 | |
michael@0 | 319 | //------------------------------------------------------------------------------ |
michael@0 | 320 | tests.push({ |
michael@0 | 321 | name: "C.1", |
michael@0 | 322 | desc: "fix missing Places root", |
michael@0 | 323 | |
michael@0 | 324 | setup: function() { |
michael@0 | 325 | // Sanity check: ensure that roots are intact. |
michael@0 | 326 | do_check_eq(bs.getFolderIdForItem(bs.placesRoot), 0); |
michael@0 | 327 | do_check_eq(bs.getFolderIdForItem(bs.bookmarksMenuFolder), bs.placesRoot); |
michael@0 | 328 | do_check_eq(bs.getFolderIdForItem(bs.tagsFolder), bs.placesRoot); |
michael@0 | 329 | do_check_eq(bs.getFolderIdForItem(bs.unfiledBookmarksFolder), bs.placesRoot); |
michael@0 | 330 | do_check_eq(bs.getFolderIdForItem(bs.toolbarFolder), bs.placesRoot); |
michael@0 | 331 | |
michael@0 | 332 | // Remove the root. |
michael@0 | 333 | mDBConn.executeSimpleSQL("DELETE FROM moz_bookmarks WHERE parent = 0"); |
michael@0 | 334 | let stmt = mDBConn.createStatement("SELECT id FROM moz_bookmarks WHERE parent = 0"); |
michael@0 | 335 | do_check_false(stmt.executeStep()); |
michael@0 | 336 | stmt.finalize(); |
michael@0 | 337 | }, |
michael@0 | 338 | |
michael@0 | 339 | check: function() { |
michael@0 | 340 | // Ensure the roots have been correctly restored. |
michael@0 | 341 | do_check_eq(bs.getFolderIdForItem(bs.placesRoot), 0); |
michael@0 | 342 | do_check_eq(bs.getFolderIdForItem(bs.bookmarksMenuFolder), bs.placesRoot); |
michael@0 | 343 | do_check_eq(bs.getFolderIdForItem(bs.tagsFolder), bs.placesRoot); |
michael@0 | 344 | do_check_eq(bs.getFolderIdForItem(bs.unfiledBookmarksFolder), bs.placesRoot); |
michael@0 | 345 | do_check_eq(bs.getFolderIdForItem(bs.toolbarFolder), bs.placesRoot); |
michael@0 | 346 | } |
michael@0 | 347 | }); |
michael@0 | 348 | |
michael@0 | 349 | //------------------------------------------------------------------------------ |
michael@0 | 350 | tests.push({ |
michael@0 | 351 | name: "C.2", |
michael@0 | 352 | desc: "Fix roots titles", |
michael@0 | 353 | |
michael@0 | 354 | setup: function() { |
michael@0 | 355 | // Sanity check: ensure that roots titles are correct. We can use our check. |
michael@0 | 356 | this.check(); |
michael@0 | 357 | // Change some roots' titles. |
michael@0 | 358 | bs.setItemTitle(bs.placesRoot, "bad title"); |
michael@0 | 359 | do_check_eq(bs.getItemTitle(bs.placesRoot), "bad title"); |
michael@0 | 360 | bs.setItemTitle(bs.unfiledBookmarksFolder, "bad title"); |
michael@0 | 361 | do_check_eq(bs.getItemTitle(bs.unfiledBookmarksFolder), "bad title"); |
michael@0 | 362 | }, |
michael@0 | 363 | |
michael@0 | 364 | check: function() { |
michael@0 | 365 | // Ensure all roots titles are correct. |
michael@0 | 366 | do_check_eq(bs.getItemTitle(bs.placesRoot), ""); |
michael@0 | 367 | do_check_eq(bs.getItemTitle(bs.bookmarksMenuFolder), |
michael@0 | 368 | PlacesUtils.getString("BookmarksMenuFolderTitle")); |
michael@0 | 369 | do_check_eq(bs.getItemTitle(bs.tagsFolder), |
michael@0 | 370 | PlacesUtils.getString("TagsFolderTitle")); |
michael@0 | 371 | do_check_eq(bs.getItemTitle(bs.unfiledBookmarksFolder), |
michael@0 | 372 | PlacesUtils.getString("UnsortedBookmarksFolderTitle")); |
michael@0 | 373 | do_check_eq(bs.getItemTitle(bs.toolbarFolder), |
michael@0 | 374 | PlacesUtils.getString("BookmarksToolbarFolderTitle")); |
michael@0 | 375 | } |
michael@0 | 376 | }); |
michael@0 | 377 | |
michael@0 | 378 | //------------------------------------------------------------------------------ |
michael@0 | 379 | |
michael@0 | 380 | tests.push({ |
michael@0 | 381 | name: "D.1", |
michael@0 | 382 | desc: "Remove items without a valid place", |
michael@0 | 383 | |
michael@0 | 384 | _validItemId: null, |
michael@0 | 385 | _invalidItemId: null, |
michael@0 | 386 | _placeId: null, |
michael@0 | 387 | |
michael@0 | 388 | setup: function() { |
michael@0 | 389 | // Add a place to ensure place_id = 1 is valid |
michael@0 | 390 | this.placeId = addPlace(); |
michael@0 | 391 | // Insert a valid bookmark |
michael@0 | 392 | this._validItemId = addBookmark(this.placeId); |
michael@0 | 393 | // Insert a bookmark with an invalid place |
michael@0 | 394 | this._invalidItemId = addBookmark(1337); |
michael@0 | 395 | }, |
michael@0 | 396 | |
michael@0 | 397 | check: function() { |
michael@0 | 398 | // Check that valid bookmark is still there |
michael@0 | 399 | let stmt = mDBConn.createStatement("SELECT id FROM moz_bookmarks WHERE id = :item_id"); |
michael@0 | 400 | stmt.params["item_id"] = this._validItemId; |
michael@0 | 401 | do_check_true(stmt.executeStep()); |
michael@0 | 402 | stmt.reset(); |
michael@0 | 403 | // Check that invalid bookmark has been removed |
michael@0 | 404 | stmt.params["item_id"] = this._invalidItemId; |
michael@0 | 405 | do_check_false(stmt.executeStep()); |
michael@0 | 406 | stmt.finalize(); |
michael@0 | 407 | } |
michael@0 | 408 | }); |
michael@0 | 409 | |
michael@0 | 410 | //------------------------------------------------------------------------------ |
michael@0 | 411 | |
michael@0 | 412 | tests.push({ |
michael@0 | 413 | name: "D.2", |
michael@0 | 414 | desc: "Remove items that are not uri bookmarks from tag containers", |
michael@0 | 415 | |
michael@0 | 416 | _tagId: null, |
michael@0 | 417 | _bookmarkId: null, |
michael@0 | 418 | _separatorId: null, |
michael@0 | 419 | _folderId: null, |
michael@0 | 420 | _placeId: null, |
michael@0 | 421 | |
michael@0 | 422 | setup: function() { |
michael@0 | 423 | // Add a place to ensure place_id = 1 is valid |
michael@0 | 424 | this._placeId = addPlace(); |
michael@0 | 425 | // Create a tag |
michael@0 | 426 | this._tagId = addBookmark(null, bs.TYPE_FOLDER, bs.tagsFolder); |
michael@0 | 427 | // Insert a bookmark in the tag |
michael@0 | 428 | this._bookmarkId = addBookmark(this._placeId, bs.TYPE_BOOKMARK, this._tagId); |
michael@0 | 429 | // Insert a separator in the tag |
michael@0 | 430 | this._separatorId = addBookmark(null, bs.TYPE_SEPARATOR, this._tagId); |
michael@0 | 431 | // Insert a folder in the tag |
michael@0 | 432 | this._folderId = addBookmark(null, bs.TYPE_FOLDER, this._tagId); |
michael@0 | 433 | }, |
michael@0 | 434 | |
michael@0 | 435 | check: function() { |
michael@0 | 436 | // Check that valid bookmark is still there |
michael@0 | 437 | let stmt = mDBConn.createStatement("SELECT id FROM moz_bookmarks WHERE type = :type AND parent = :parent"); |
michael@0 | 438 | stmt.params["type"] = bs.TYPE_BOOKMARK; |
michael@0 | 439 | stmt.params["parent"] = this._tagId; |
michael@0 | 440 | do_check_true(stmt.executeStep()); |
michael@0 | 441 | stmt.reset(); |
michael@0 | 442 | // Check that separator is no more there |
michael@0 | 443 | stmt.params["type"] = bs.TYPE_SEPARATOR; |
michael@0 | 444 | stmt.params["parent"] = this._tagId; |
michael@0 | 445 | do_check_false(stmt.executeStep()); |
michael@0 | 446 | stmt.reset(); |
michael@0 | 447 | // Check that folder is no more there |
michael@0 | 448 | stmt.params["type"] = bs.TYPE_FOLDER; |
michael@0 | 449 | stmt.params["parent"] = this._tagId; |
michael@0 | 450 | do_check_false(stmt.executeStep()); |
michael@0 | 451 | stmt.finalize(); |
michael@0 | 452 | } |
michael@0 | 453 | }); |
michael@0 | 454 | |
michael@0 | 455 | //------------------------------------------------------------------------------ |
michael@0 | 456 | |
michael@0 | 457 | tests.push({ |
michael@0 | 458 | name: "D.3", |
michael@0 | 459 | desc: "Remove empty tags", |
michael@0 | 460 | |
michael@0 | 461 | _tagId: null, |
michael@0 | 462 | _bookmarkId: null, |
michael@0 | 463 | _emptyTagId: null, |
michael@0 | 464 | _placeId: null, |
michael@0 | 465 | |
michael@0 | 466 | setup: function() { |
michael@0 | 467 | // Add a place to ensure place_id = 1 is valid |
michael@0 | 468 | this._placeId = addPlace(); |
michael@0 | 469 | // Create a tag |
michael@0 | 470 | this._tagId = addBookmark(null, bs.TYPE_FOLDER, bs.tagsFolder); |
michael@0 | 471 | // Insert a bookmark in the tag |
michael@0 | 472 | this._bookmarkId = addBookmark(this._placeId, bs.TYPE_BOOKMARK, this._tagId); |
michael@0 | 473 | // Create another tag (empty) |
michael@0 | 474 | this._emptyTagId = addBookmark(null, bs.TYPE_FOLDER, bs.tagsFolder); |
michael@0 | 475 | }, |
michael@0 | 476 | |
michael@0 | 477 | check: function() { |
michael@0 | 478 | // Check that valid bookmark is still there |
michael@0 | 479 | let stmt = mDBConn.createStatement("SELECT id FROM moz_bookmarks WHERE id = :id AND type = :type AND parent = :parent"); |
michael@0 | 480 | stmt.params["id"] = this._bookmarkId; |
michael@0 | 481 | stmt.params["type"] = bs.TYPE_BOOKMARK; |
michael@0 | 482 | stmt.params["parent"] = this._tagId; |
michael@0 | 483 | do_check_true(stmt.executeStep()); |
michael@0 | 484 | stmt.reset(); |
michael@0 | 485 | stmt.params["id"] = this._tagId; |
michael@0 | 486 | stmt.params["type"] = bs.TYPE_FOLDER; |
michael@0 | 487 | stmt.params["parent"] = bs.tagsFolder; |
michael@0 | 488 | do_check_true(stmt.executeStep()); |
michael@0 | 489 | stmt.reset(); |
michael@0 | 490 | stmt.params["id"] = this._emptyTagId; |
michael@0 | 491 | stmt.params["type"] = bs.TYPE_FOLDER; |
michael@0 | 492 | stmt.params["parent"] = bs.tagsFolder; |
michael@0 | 493 | do_check_false(stmt.executeStep()); |
michael@0 | 494 | stmt.finalize(); |
michael@0 | 495 | } |
michael@0 | 496 | }); |
michael@0 | 497 | |
michael@0 | 498 | //------------------------------------------------------------------------------ |
michael@0 | 499 | |
michael@0 | 500 | tests.push({ |
michael@0 | 501 | name: "D.4", |
michael@0 | 502 | desc: "Move orphan items to unsorted folder", |
michael@0 | 503 | |
michael@0 | 504 | _orphanBookmarkId: null, |
michael@0 | 505 | _orphanSeparatorId: null, |
michael@0 | 506 | _orphanFolderId: null, |
michael@0 | 507 | _bookmarkId: null, |
michael@0 | 508 | _placeId: null, |
michael@0 | 509 | |
michael@0 | 510 | setup: function() { |
michael@0 | 511 | // Add a place to ensure place_id = 1 is valid |
michael@0 | 512 | this._placeId = addPlace(); |
michael@0 | 513 | // Insert an orphan bookmark |
michael@0 | 514 | this._orphanBookmarkId = addBookmark(this._placeId, bs.TYPE_BOOKMARK, 8888); |
michael@0 | 515 | // Insert an orphan separator |
michael@0 | 516 | this._orphanSeparatorId = addBookmark(null, bs.TYPE_SEPARATOR, 8888); |
michael@0 | 517 | // Insert a orphan folder |
michael@0 | 518 | this._orphanFolderId = addBookmark(null, bs.TYPE_FOLDER, 8888); |
michael@0 | 519 | // Create a child of the last created folder |
michael@0 | 520 | this._bookmarkId = addBookmark(this._placeId, bs.TYPE_BOOKMARK, this._orphanFolderId); |
michael@0 | 521 | }, |
michael@0 | 522 | |
michael@0 | 523 | check: function() { |
michael@0 | 524 | // Check that bookmarks are now children of a real folder (unsorted) |
michael@0 | 525 | let stmt = mDBConn.createStatement("SELECT id FROM moz_bookmarks WHERE id = :item_id AND parent = :parent"); |
michael@0 | 526 | stmt.params["item_id"] = this._orphanBookmarkId; |
michael@0 | 527 | stmt.params["parent"] = bs.unfiledBookmarksFolder; |
michael@0 | 528 | do_check_true(stmt.executeStep()); |
michael@0 | 529 | stmt.reset(); |
michael@0 | 530 | stmt.params["item_id"] = this._orphanSeparatorId; |
michael@0 | 531 | stmt.params["parent"] = bs.unfiledBookmarksFolder; |
michael@0 | 532 | do_check_true(stmt.executeStep()); |
michael@0 | 533 | stmt.reset(); |
michael@0 | 534 | stmt.params["item_id"] = this._orphanFolderId; |
michael@0 | 535 | stmt.params["parent"] = bs.unfiledBookmarksFolder; |
michael@0 | 536 | do_check_true(stmt.executeStep()); |
michael@0 | 537 | stmt.reset(); |
michael@0 | 538 | stmt.params["item_id"] = this._bookmarkId; |
michael@0 | 539 | stmt.params["parent"] = this._orphanFolderId; |
michael@0 | 540 | do_check_true(stmt.executeStep()); |
michael@0 | 541 | stmt.finalize(); |
michael@0 | 542 | } |
michael@0 | 543 | }); |
michael@0 | 544 | |
michael@0 | 545 | //------------------------------------------------------------------------------ |
michael@0 | 546 | |
michael@0 | 547 | tests.push({ |
michael@0 | 548 | name: "D.5", |
michael@0 | 549 | desc: "Fix wrong keywords", |
michael@0 | 550 | |
michael@0 | 551 | _validKeywordItemId: null, |
michael@0 | 552 | _invalidKeywordItemId: null, |
michael@0 | 553 | _validKeywordId: 1, |
michael@0 | 554 | _invalidKeywordId: 8888, |
michael@0 | 555 | _placeId: null, |
michael@0 | 556 | |
michael@0 | 557 | setup: function() { |
michael@0 | 558 | // Insert a keyword |
michael@0 | 559 | let stmt = mDBConn.createStatement("INSERT INTO moz_keywords (id, keyword) VALUES(:id, :keyword)"); |
michael@0 | 560 | stmt.params["id"] = this._validKeywordId; |
michael@0 | 561 | stmt.params["keyword"] = "used"; |
michael@0 | 562 | stmt.execute(); |
michael@0 | 563 | stmt.finalize(); |
michael@0 | 564 | // Add a place to ensure place_id = 1 is valid |
michael@0 | 565 | this._placeId = addPlace(); |
michael@0 | 566 | // Add a bookmark using the keyword |
michael@0 | 567 | this._validKeywordItemId = addBookmark(this._placeId, bs.TYPE_BOOKMARK, bs.unfiledBookmarksFolder, this._validKeywordId); |
michael@0 | 568 | // Add a bookmark using a nonexistent keyword |
michael@0 | 569 | this._invalidKeywordItemId = addBookmark(this._placeId, bs.TYPE_BOOKMARK, bs.unfiledBookmarksFolder, this._invalidKeywordId); |
michael@0 | 570 | }, |
michael@0 | 571 | |
michael@0 | 572 | check: function() { |
michael@0 | 573 | // Check that item with valid keyword is there |
michael@0 | 574 | let stmt = mDBConn.createStatement("SELECT id FROM moz_bookmarks WHERE id = :item_id AND keyword_id = :keyword"); |
michael@0 | 575 | stmt.params["item_id"] = this._validKeywordItemId; |
michael@0 | 576 | stmt.params["keyword"] = this._validKeywordId; |
michael@0 | 577 | do_check_true(stmt.executeStep()); |
michael@0 | 578 | stmt.reset(); |
michael@0 | 579 | // Check that item with invalid keyword has been corrected |
michael@0 | 580 | stmt.params["item_id"] = this._invalidKeywordItemId; |
michael@0 | 581 | stmt.params["keyword"] = this._invalidKeywordId; |
michael@0 | 582 | do_check_false(stmt.executeStep()); |
michael@0 | 583 | stmt.finalize(); |
michael@0 | 584 | // Check that item with invalid keyword has not been removed |
michael@0 | 585 | stmt = mDBConn.createStatement("SELECT id FROM moz_bookmarks WHERE id = :item_id"); |
michael@0 | 586 | stmt.params["item_id"] = this._invalidKeywordItemId; |
michael@0 | 587 | do_check_true(stmt.executeStep()); |
michael@0 | 588 | stmt.finalize(); |
michael@0 | 589 | } |
michael@0 | 590 | }); |
michael@0 | 591 | |
michael@0 | 592 | //------------------------------------------------------------------------------ |
michael@0 | 593 | |
michael@0 | 594 | tests.push({ |
michael@0 | 595 | name: "D.6", |
michael@0 | 596 | desc: "Fix wrong item types | bookmarks", |
michael@0 | 597 | |
michael@0 | 598 | _separatorId: null, |
michael@0 | 599 | _folderId: null, |
michael@0 | 600 | _placeId: null, |
michael@0 | 601 | |
michael@0 | 602 | setup: function() { |
michael@0 | 603 | // Add a place to ensure place_id = 1 is valid |
michael@0 | 604 | this._placeId = addPlace(); |
michael@0 | 605 | // Add a separator with a fk |
michael@0 | 606 | this._separatorId = addBookmark(this._placeId, bs.TYPE_SEPARATOR); |
michael@0 | 607 | // Add a folder with a fk |
michael@0 | 608 | this._folderId = addBookmark(this._placeId, bs.TYPE_FOLDER); |
michael@0 | 609 | }, |
michael@0 | 610 | |
michael@0 | 611 | check: function() { |
michael@0 | 612 | // Check that items with an fk have been converted to bookmarks |
michael@0 | 613 | let stmt = mDBConn.createStatement("SELECT id FROM moz_bookmarks WHERE id = :item_id AND type = :type"); |
michael@0 | 614 | stmt.params["item_id"] = this._separatorId; |
michael@0 | 615 | stmt.params["type"] = bs.TYPE_BOOKMARK; |
michael@0 | 616 | do_check_true(stmt.executeStep()); |
michael@0 | 617 | stmt.reset(); |
michael@0 | 618 | stmt.params["item_id"] = this._folderId; |
michael@0 | 619 | stmt.params["type"] = bs.TYPE_BOOKMARK; |
michael@0 | 620 | do_check_true(stmt.executeStep()); |
michael@0 | 621 | stmt.finalize(); |
michael@0 | 622 | } |
michael@0 | 623 | }); |
michael@0 | 624 | |
michael@0 | 625 | //------------------------------------------------------------------------------ |
michael@0 | 626 | |
michael@0 | 627 | tests.push({ |
michael@0 | 628 | name: "D.7", |
michael@0 | 629 | desc: "Fix wrong item types | bookmarks", |
michael@0 | 630 | |
michael@0 | 631 | _validBookmarkId: null, |
michael@0 | 632 | _invalidBookmarkId: null, |
michael@0 | 633 | _placeId: null, |
michael@0 | 634 | |
michael@0 | 635 | setup: function() { |
michael@0 | 636 | // Add a place to ensure place_id = 1 is valid |
michael@0 | 637 | this._placeId = addPlace(); |
michael@0 | 638 | // Add a bookmark with a valid place id |
michael@0 | 639 | this._validBookmarkId = addBookmark(this._placeId, bs.TYPE_BOOKMARK); |
michael@0 | 640 | // Add a bookmark with a null place id |
michael@0 | 641 | this._invalidBookmarkId = addBookmark(null, bs.TYPE_BOOKMARK); |
michael@0 | 642 | }, |
michael@0 | 643 | |
michael@0 | 644 | check: function() { |
michael@0 | 645 | // Check valid bookmark |
michael@0 | 646 | let stmt = mDBConn.createStatement("SELECT id FROM moz_bookmarks WHERE id = :item_id AND type = :type"); |
michael@0 | 647 | stmt.params["item_id"] = this._validBookmarkId; |
michael@0 | 648 | stmt.params["type"] = bs.TYPE_BOOKMARK; |
michael@0 | 649 | do_check_true(stmt.executeStep()); |
michael@0 | 650 | stmt.reset(); |
michael@0 | 651 | // Check invalid bookmark has been converted to a folder |
michael@0 | 652 | stmt.params["item_id"] = this._invalidBookmarkId; |
michael@0 | 653 | stmt.params["type"] = bs.TYPE_FOLDER; |
michael@0 | 654 | do_check_true(stmt.executeStep()); |
michael@0 | 655 | stmt.finalize(); |
michael@0 | 656 | } |
michael@0 | 657 | }); |
michael@0 | 658 | |
michael@0 | 659 | //------------------------------------------------------------------------------ |
michael@0 | 660 | |
michael@0 | 661 | tests.push({ |
michael@0 | 662 | name: "D.9", |
michael@0 | 663 | desc: "Fix wrong parents", |
michael@0 | 664 | |
michael@0 | 665 | _bookmarkId: null, |
michael@0 | 666 | _separatorId: null, |
michael@0 | 667 | _bookmarkId1: null, |
michael@0 | 668 | _bookmarkId2: null, |
michael@0 | 669 | _placeId: null, |
michael@0 | 670 | |
michael@0 | 671 | setup: function() { |
michael@0 | 672 | // Add a place to ensure place_id = 1 is valid |
michael@0 | 673 | this._placeId = addPlace(); |
michael@0 | 674 | // Insert a bookmark |
michael@0 | 675 | this._bookmarkId = addBookmark(this._placeId, bs.TYPE_BOOKMARK); |
michael@0 | 676 | // Insert a separator |
michael@0 | 677 | this._separatorId = addBookmark(null, bs.TYPE_SEPARATOR); |
michael@0 | 678 | // Create 3 children of these items |
michael@0 | 679 | this._bookmarkId1 = addBookmark(this._placeId, bs.TYPE_BOOKMARK, this._bookmarkId); |
michael@0 | 680 | this._bookmarkId2 = addBookmark(this._placeId, bs.TYPE_BOOKMARK, this._separatorId); |
michael@0 | 681 | }, |
michael@0 | 682 | |
michael@0 | 683 | check: function() { |
michael@0 | 684 | // Check that bookmarks are now children of a real folder (unsorted) |
michael@0 | 685 | let stmt = mDBConn.createStatement("SELECT id FROM moz_bookmarks WHERE id = :item_id AND parent = :parent"); |
michael@0 | 686 | stmt.params["item_id"] = this._bookmarkId1; |
michael@0 | 687 | stmt.params["parent"] = bs.unfiledBookmarksFolder; |
michael@0 | 688 | do_check_true(stmt.executeStep()); |
michael@0 | 689 | stmt.reset(); |
michael@0 | 690 | stmt.params["item_id"] = this._bookmarkId2; |
michael@0 | 691 | stmt.params["parent"] = bs.unfiledBookmarksFolder; |
michael@0 | 692 | do_check_true(stmt.executeStep()); |
michael@0 | 693 | stmt.finalize(); |
michael@0 | 694 | } |
michael@0 | 695 | }); |
michael@0 | 696 | |
michael@0 | 697 | //------------------------------------------------------------------------------ |
michael@0 | 698 | |
michael@0 | 699 | tests.push({ |
michael@0 | 700 | name: "D.10", |
michael@0 | 701 | desc: "Recalculate positions", |
michael@0 | 702 | |
michael@0 | 703 | _unfiledBookmarks: [], |
michael@0 | 704 | _toolbarBookmarks: [], |
michael@0 | 705 | |
michael@0 | 706 | setup: function() { |
michael@0 | 707 | const NUM_BOOKMARKS = 20; |
michael@0 | 708 | bs.runInBatchMode({ |
michael@0 | 709 | runBatched: function (aUserData) { |
michael@0 | 710 | // Add bookmarks to two folders to better perturbate the table. |
michael@0 | 711 | for (let i = 0; i < NUM_BOOKMARKS; i++) { |
michael@0 | 712 | bs.insertBookmark(PlacesUtils.unfiledBookmarksFolderId, |
michael@0 | 713 | NetUtil.newURI("http://example.com/"), |
michael@0 | 714 | bs.DEFAULT_INDEX, "testbookmark"); |
michael@0 | 715 | } |
michael@0 | 716 | for (let i = 0; i < NUM_BOOKMARKS; i++) { |
michael@0 | 717 | bs.insertBookmark(PlacesUtils.toolbarFolderId, |
michael@0 | 718 | NetUtil.newURI("http://example.com/"), |
michael@0 | 719 | bs.DEFAULT_INDEX, "testbookmark"); |
michael@0 | 720 | } |
michael@0 | 721 | } |
michael@0 | 722 | }, null); |
michael@0 | 723 | |
michael@0 | 724 | function randomize_positions(aParent, aResultArray) { |
michael@0 | 725 | let stmt = mDBConn.createStatement( |
michael@0 | 726 | "UPDATE moz_bookmarks SET position = :rand " + |
michael@0 | 727 | "WHERE id IN ( " + |
michael@0 | 728 | "SELECT id FROM moz_bookmarks WHERE parent = :parent " + |
michael@0 | 729 | "ORDER BY RANDOM() LIMIT 1 " + |
michael@0 | 730 | ") " |
michael@0 | 731 | ); |
michael@0 | 732 | for (let i = 0; i < (NUM_BOOKMARKS / 2); i++) { |
michael@0 | 733 | stmt.params["parent"] = aParent; |
michael@0 | 734 | stmt.params["rand"] = Math.round(Math.random() * (NUM_BOOKMARKS - 1)); |
michael@0 | 735 | stmt.execute(); |
michael@0 | 736 | stmt.reset(); |
michael@0 | 737 | } |
michael@0 | 738 | stmt.finalize(); |
michael@0 | 739 | |
michael@0 | 740 | // Build the expected ordered list of bookmarks. |
michael@0 | 741 | stmt = mDBConn.createStatement( |
michael@0 | 742 | "SELECT id, position " + |
michael@0 | 743 | "FROM moz_bookmarks WHERE parent = :parent " + |
michael@0 | 744 | "ORDER BY position ASC, ROWID ASC " |
michael@0 | 745 | ); |
michael@0 | 746 | stmt.params["parent"] = aParent; |
michael@0 | 747 | while (stmt.executeStep()) { |
michael@0 | 748 | aResultArray.push(stmt.row.id); |
michael@0 | 749 | print(stmt.row.id + "\t" + stmt.row.position + "\t" + |
michael@0 | 750 | (aResultArray.length - 1)); |
michael@0 | 751 | } |
michael@0 | 752 | stmt.finalize(); |
michael@0 | 753 | } |
michael@0 | 754 | |
michael@0 | 755 | // Set random positions for the added bookmarks. |
michael@0 | 756 | randomize_positions(PlacesUtils.unfiledBookmarksFolderId, |
michael@0 | 757 | this._unfiledBookmarks); |
michael@0 | 758 | randomize_positions(PlacesUtils.toolbarFolderId, this._toolbarBookmarks); |
michael@0 | 759 | }, |
michael@0 | 760 | |
michael@0 | 761 | check: function() { |
michael@0 | 762 | function check_order(aParent, aResultArray) { |
michael@0 | 763 | // Build the expected ordered list of bookmarks. |
michael@0 | 764 | let stmt = mDBConn.createStatement( |
michael@0 | 765 | "SELECT id, position FROM moz_bookmarks WHERE parent = :parent " + |
michael@0 | 766 | "ORDER BY position ASC" |
michael@0 | 767 | ); |
michael@0 | 768 | stmt.params["parent"] = aParent; |
michael@0 | 769 | let pass = true; |
michael@0 | 770 | while (stmt.executeStep()) { |
michael@0 | 771 | print(stmt.row.id + "\t" + stmt.row.position); |
michael@0 | 772 | if (aResultArray.indexOf(stmt.row.id) != stmt.row.position) { |
michael@0 | 773 | pass = false; |
michael@0 | 774 | } |
michael@0 | 775 | } |
michael@0 | 776 | stmt.finalize(); |
michael@0 | 777 | if (!pass) { |
michael@0 | 778 | dump_table("moz_bookmarks"); |
michael@0 | 779 | do_throw("Unexpected unfiled bookmarks order."); |
michael@0 | 780 | } |
michael@0 | 781 | } |
michael@0 | 782 | |
michael@0 | 783 | check_order(PlacesUtils.unfiledBookmarksFolderId, this._unfiledBookmarks); |
michael@0 | 784 | check_order(PlacesUtils.toolbarFolderId, this._toolbarBookmarks); |
michael@0 | 785 | } |
michael@0 | 786 | }); |
michael@0 | 787 | |
michael@0 | 788 | //------------------------------------------------------------------------------ |
michael@0 | 789 | |
michael@0 | 790 | tests.push({ |
michael@0 | 791 | name: "D.12", |
michael@0 | 792 | desc: "Fix empty-named tags", |
michael@0 | 793 | |
michael@0 | 794 | setup: function() { |
michael@0 | 795 | // Add a place to ensure place_id = 1 is valid |
michael@0 | 796 | let placeId = addPlace(); |
michael@0 | 797 | // Create a empty-named tag. |
michael@0 | 798 | this._untitledTagId = addBookmark(null, bs.TYPE_FOLDER, bs.tagsFolder, null, null, ""); |
michael@0 | 799 | // Insert a bookmark in the tag, otherwise it will be removed. |
michael@0 | 800 | addBookmark(placeId, bs.TYPE_BOOKMARK, this._untitledTagId); |
michael@0 | 801 | // Create a empty-named folder. |
michael@0 | 802 | this._untitledFolderId = addBookmark(null, bs.TYPE_FOLDER, bs.toolbarFolder, null, null, ""); |
michael@0 | 803 | // Create a titled tag. |
michael@0 | 804 | this._titledTagId = addBookmark(null, bs.TYPE_FOLDER, bs.tagsFolder, null, null, "titledTag"); |
michael@0 | 805 | // Insert a bookmark in the tag, otherwise it will be removed. |
michael@0 | 806 | addBookmark(placeId, bs.TYPE_BOOKMARK, this._titledTagId); |
michael@0 | 807 | // Create a titled folder. |
michael@0 | 808 | this._titledFolderId = addBookmark(null, bs.TYPE_FOLDER, bs.toolbarFolder, null, null, "titledFolder"); |
michael@0 | 809 | }, |
michael@0 | 810 | |
michael@0 | 811 | check: function() { |
michael@0 | 812 | // Check that valid bookmark is still there |
michael@0 | 813 | let stmt = mDBConn.createStatement( |
michael@0 | 814 | "SELECT title FROM moz_bookmarks WHERE id = :id" |
michael@0 | 815 | ); |
michael@0 | 816 | stmt.params["id"] = this._untitledTagId; |
michael@0 | 817 | do_check_true(stmt.executeStep()); |
michael@0 | 818 | do_check_eq(stmt.row.title, "(notitle)"); |
michael@0 | 819 | stmt.reset(); |
michael@0 | 820 | stmt.params["id"] = this._untitledFolderId; |
michael@0 | 821 | do_check_true(stmt.executeStep()); |
michael@0 | 822 | do_check_eq(stmt.row.title, ""); |
michael@0 | 823 | stmt.reset(); |
michael@0 | 824 | stmt.params["id"] = this._titledTagId; |
michael@0 | 825 | do_check_true(stmt.executeStep()); |
michael@0 | 826 | do_check_eq(stmt.row.title, "titledTag"); |
michael@0 | 827 | stmt.reset(); |
michael@0 | 828 | stmt.params["id"] = this._titledFolderId; |
michael@0 | 829 | do_check_true(stmt.executeStep()); |
michael@0 | 830 | do_check_eq(stmt.row.title, "titledFolder"); |
michael@0 | 831 | stmt.finalize(); |
michael@0 | 832 | } |
michael@0 | 833 | }); |
michael@0 | 834 | |
michael@0 | 835 | //------------------------------------------------------------------------------ |
michael@0 | 836 | |
michael@0 | 837 | tests.push({ |
michael@0 | 838 | name: "E.1", |
michael@0 | 839 | desc: "Remove orphan icons", |
michael@0 | 840 | |
michael@0 | 841 | _placeId: null, |
michael@0 | 842 | |
michael@0 | 843 | setup: function() { |
michael@0 | 844 | // Insert favicon entries |
michael@0 | 845 | let stmt = mDBConn.createStatement("INSERT INTO moz_favicons (id, url) VALUES(:favicon_id, :url)"); |
michael@0 | 846 | stmt.params["favicon_id"] = 1; |
michael@0 | 847 | stmt.params["url"] = "http://www1.mozilla.org/favicon.ico"; |
michael@0 | 848 | stmt.execute(); |
michael@0 | 849 | stmt.reset(); |
michael@0 | 850 | stmt.params["favicon_id"] = 2; |
michael@0 | 851 | stmt.params["url"] = "http://www2.mozilla.org/favicon.ico"; |
michael@0 | 852 | stmt.execute(); |
michael@0 | 853 | stmt.finalize(); |
michael@0 | 854 | // Insert a place using the existing favicon entry |
michael@0 | 855 | this._placeId = addPlace("http://www.mozilla.org", 1); |
michael@0 | 856 | }, |
michael@0 | 857 | |
michael@0 | 858 | check: function() { |
michael@0 | 859 | // Check that used icon is still there |
michael@0 | 860 | let stmt = mDBConn.createStatement("SELECT id FROM moz_favicons WHERE id = :favicon_id"); |
michael@0 | 861 | stmt.params["favicon_id"] = 1; |
michael@0 | 862 | do_check_true(stmt.executeStep()); |
michael@0 | 863 | stmt.reset(); |
michael@0 | 864 | // Check that unused icon has been removed |
michael@0 | 865 | stmt.params["favicon_id"] = 2; |
michael@0 | 866 | do_check_false(stmt.executeStep()); |
michael@0 | 867 | stmt.finalize(); |
michael@0 | 868 | } |
michael@0 | 869 | }); |
michael@0 | 870 | |
michael@0 | 871 | //------------------------------------------------------------------------------ |
michael@0 | 872 | |
michael@0 | 873 | tests.push({ |
michael@0 | 874 | name: "F.1", |
michael@0 | 875 | desc: "Remove orphan visits", |
michael@0 | 876 | |
michael@0 | 877 | _placeId: null, |
michael@0 | 878 | _invalidPlaceId: 1337, |
michael@0 | 879 | |
michael@0 | 880 | setup: function() { |
michael@0 | 881 | // Add a place to ensure place_id = 1 is valid |
michael@0 | 882 | this._placeId = addPlace(); |
michael@0 | 883 | // Add a valid visit and an invalid one |
michael@0 | 884 | stmt = mDBConn.createStatement("INSERT INTO moz_historyvisits(place_id) VALUES (:place_id)"); |
michael@0 | 885 | stmt.params["place_id"] = this._placeId; |
michael@0 | 886 | stmt.execute(); |
michael@0 | 887 | stmt.reset(); |
michael@0 | 888 | stmt.params["place_id"] = this._invalidPlaceId; |
michael@0 | 889 | stmt.execute(); |
michael@0 | 890 | stmt.finalize(); |
michael@0 | 891 | }, |
michael@0 | 892 | |
michael@0 | 893 | check: function() { |
michael@0 | 894 | // Check that valid visit is still there |
michael@0 | 895 | let stmt = mDBConn.createStatement("SELECT id FROM moz_historyvisits WHERE place_id = :place_id"); |
michael@0 | 896 | stmt.params["place_id"] = this._placeId; |
michael@0 | 897 | do_check_true(stmt.executeStep()); |
michael@0 | 898 | stmt.reset(); |
michael@0 | 899 | // Check that invalid visit has been removed |
michael@0 | 900 | stmt.params["place_id"] = this._invalidPlaceId; |
michael@0 | 901 | do_check_false(stmt.executeStep()); |
michael@0 | 902 | stmt.finalize(); |
michael@0 | 903 | } |
michael@0 | 904 | }); |
michael@0 | 905 | |
michael@0 | 906 | //------------------------------------------------------------------------------ |
michael@0 | 907 | |
michael@0 | 908 | tests.push({ |
michael@0 | 909 | name: "G.1", |
michael@0 | 910 | desc: "Remove orphan input history", |
michael@0 | 911 | |
michael@0 | 912 | _placeId: null, |
michael@0 | 913 | _invalidPlaceId: 1337, |
michael@0 | 914 | |
michael@0 | 915 | setup: function() { |
michael@0 | 916 | // Add a place to ensure place_id = 1 is valid |
michael@0 | 917 | this._placeId = addPlace(); |
michael@0 | 918 | // Add input history entries |
michael@0 | 919 | let stmt = mDBConn.createStatement("INSERT INTO moz_inputhistory (place_id, input) VALUES (:place_id, :input)"); |
michael@0 | 920 | stmt.params["place_id"] = this._placeId; |
michael@0 | 921 | stmt.params["input"] = "moz"; |
michael@0 | 922 | stmt.execute(); |
michael@0 | 923 | stmt.reset(); |
michael@0 | 924 | stmt.params["place_id"] = this._invalidPlaceId; |
michael@0 | 925 | stmt.params["input"] = "moz"; |
michael@0 | 926 | stmt.execute(); |
michael@0 | 927 | stmt.finalize(); |
michael@0 | 928 | }, |
michael@0 | 929 | |
michael@0 | 930 | check: function() { |
michael@0 | 931 | // Check that inputhistory on valid place is still there |
michael@0 | 932 | let stmt = mDBConn.createStatement("SELECT place_id FROM moz_inputhistory WHERE place_id = :place_id"); |
michael@0 | 933 | stmt.params["place_id"] = this._placeId; |
michael@0 | 934 | do_check_true(stmt.executeStep()); |
michael@0 | 935 | stmt.reset(); |
michael@0 | 936 | // Check that inputhistory on invalid place has gone |
michael@0 | 937 | stmt.params["place_id"] = this._invalidPlaceId; |
michael@0 | 938 | do_check_false(stmt.executeStep()); |
michael@0 | 939 | stmt.finalize(); |
michael@0 | 940 | } |
michael@0 | 941 | }); |
michael@0 | 942 | |
michael@0 | 943 | //------------------------------------------------------------------------------ |
michael@0 | 944 | |
michael@0 | 945 | tests.push({ |
michael@0 | 946 | name: "H.1", |
michael@0 | 947 | desc: "Remove item annos with an invalid attribute", |
michael@0 | 948 | |
michael@0 | 949 | _usedItemAttribute: "usedItem", |
michael@0 | 950 | _bookmarkId: null, |
michael@0 | 951 | _placeId: null, |
michael@0 | 952 | |
michael@0 | 953 | setup: function() { |
michael@0 | 954 | // Add a place to ensure place_id = 1 is valid |
michael@0 | 955 | this._placeId = addPlace(); |
michael@0 | 956 | // Insert a bookmark |
michael@0 | 957 | this._bookmarkId = addBookmark(this._placeId); |
michael@0 | 958 | // Add a used attribute. |
michael@0 | 959 | let stmt = mDBConn.createStatement("INSERT INTO moz_anno_attributes (name) VALUES (:anno)"); |
michael@0 | 960 | stmt.params['anno'] = this._usedItemAttribute; |
michael@0 | 961 | stmt.execute(); |
michael@0 | 962 | stmt.finalize(); |
michael@0 | 963 | stmt = mDBConn.createStatement("INSERT INTO moz_items_annos (item_id, anno_attribute_id) VALUES(:item_id, (SELECT id FROM moz_anno_attributes WHERE name = :anno))"); |
michael@0 | 964 | stmt.params['item_id'] = this._bookmarkId; |
michael@0 | 965 | stmt.params['anno'] = this._usedItemAttribute; |
michael@0 | 966 | stmt.execute(); |
michael@0 | 967 | stmt.finalize(); |
michael@0 | 968 | // Add an annotation with a nonexistent attribute |
michael@0 | 969 | stmt = mDBConn.createStatement("INSERT INTO moz_items_annos (item_id, anno_attribute_id) VALUES(:item_id, 1337)"); |
michael@0 | 970 | stmt.params['item_id'] = this._bookmarkId; |
michael@0 | 971 | stmt.execute(); |
michael@0 | 972 | stmt.finalize(); |
michael@0 | 973 | }, |
michael@0 | 974 | |
michael@0 | 975 | check: function() { |
michael@0 | 976 | // Check that used attribute is still there |
michael@0 | 977 | let stmt = mDBConn.createStatement("SELECT id FROM moz_anno_attributes WHERE name = :anno"); |
michael@0 | 978 | stmt.params['anno'] = this._usedItemAttribute; |
michael@0 | 979 | do_check_true(stmt.executeStep()); |
michael@0 | 980 | stmt.finalize(); |
michael@0 | 981 | // check that annotation with valid attribute is still there |
michael@0 | 982 | stmt = mDBConn.createStatement("SELECT id FROM moz_items_annos WHERE anno_attribute_id = (SELECT id FROM moz_anno_attributes WHERE name = :anno)"); |
michael@0 | 983 | stmt.params['anno'] = this._usedItemAttribute; |
michael@0 | 984 | do_check_true(stmt.executeStep()); |
michael@0 | 985 | stmt.finalize(); |
michael@0 | 986 | // Check that annotation with bogus attribute has been removed |
michael@0 | 987 | stmt = mDBConn.createStatement("SELECT id FROM moz_items_annos WHERE anno_attribute_id = 1337"); |
michael@0 | 988 | do_check_false(stmt.executeStep()); |
michael@0 | 989 | stmt.finalize(); |
michael@0 | 990 | } |
michael@0 | 991 | }); |
michael@0 | 992 | |
michael@0 | 993 | //------------------------------------------------------------------------------ |
michael@0 | 994 | |
michael@0 | 995 | tests.push({ |
michael@0 | 996 | name: "H.2", |
michael@0 | 997 | desc: "Remove orphan item annotations", |
michael@0 | 998 | |
michael@0 | 999 | _usedItemAttribute: "usedItem", |
michael@0 | 1000 | _bookmarkId: null, |
michael@0 | 1001 | _invalidBookmarkId: 8888, |
michael@0 | 1002 | _placeId: null, |
michael@0 | 1003 | |
michael@0 | 1004 | setup: function() { |
michael@0 | 1005 | // Add a place to ensure place_id = 1 is valid |
michael@0 | 1006 | this._placeId = addPlace(); |
michael@0 | 1007 | // Insert a bookmark |
michael@0 | 1008 | this._bookmarkId = addBookmark(this._placeId); |
michael@0 | 1009 | // Add a used attribute. |
michael@0 | 1010 | stmt = mDBConn.createStatement("INSERT INTO moz_anno_attributes (name) VALUES (:anno)"); |
michael@0 | 1011 | stmt.params['anno'] = this._usedItemAttribute; |
michael@0 | 1012 | stmt.execute(); |
michael@0 | 1013 | stmt.finalize(); |
michael@0 | 1014 | stmt = mDBConn.createStatement("INSERT INTO moz_items_annos (item_id, anno_attribute_id) VALUES (:item_id, (SELECT id FROM moz_anno_attributes WHERE name = :anno))"); |
michael@0 | 1015 | stmt.params["item_id"] = this._bookmarkId; |
michael@0 | 1016 | stmt.params["anno"] = this._usedItemAttribute; |
michael@0 | 1017 | stmt.execute(); |
michael@0 | 1018 | stmt.reset(); |
michael@0 | 1019 | // Add an annotation to a nonexistent item |
michael@0 | 1020 | stmt.params["item_id"] = this._invalidBookmarkId; |
michael@0 | 1021 | stmt.params["anno"] = this._usedItemAttribute; |
michael@0 | 1022 | stmt.execute(); |
michael@0 | 1023 | stmt.finalize(); |
michael@0 | 1024 | }, |
michael@0 | 1025 | |
michael@0 | 1026 | check: function() { |
michael@0 | 1027 | // Check that used attribute is still there |
michael@0 | 1028 | let stmt = mDBConn.createStatement("SELECT id FROM moz_anno_attributes WHERE name = :anno"); |
michael@0 | 1029 | stmt.params['anno'] = this._usedItemAttribute; |
michael@0 | 1030 | do_check_true(stmt.executeStep()); |
michael@0 | 1031 | stmt.finalize(); |
michael@0 | 1032 | // check that annotation with valid attribute is still there |
michael@0 | 1033 | stmt = mDBConn.createStatement("SELECT id FROM moz_items_annos WHERE anno_attribute_id = (SELECT id FROM moz_anno_attributes WHERE name = :anno)"); |
michael@0 | 1034 | stmt.params['anno'] = this._usedItemAttribute; |
michael@0 | 1035 | do_check_true(stmt.executeStep()); |
michael@0 | 1036 | stmt.finalize(); |
michael@0 | 1037 | // Check that an annotation to a nonexistent page has been removed |
michael@0 | 1038 | stmt = mDBConn.createStatement("SELECT id FROM moz_items_annos WHERE item_id = 8888"); |
michael@0 | 1039 | do_check_false(stmt.executeStep()); |
michael@0 | 1040 | stmt.finalize(); |
michael@0 | 1041 | } |
michael@0 | 1042 | }); |
michael@0 | 1043 | |
michael@0 | 1044 | |
michael@0 | 1045 | //------------------------------------------------------------------------------ |
michael@0 | 1046 | |
michael@0 | 1047 | tests.push({ |
michael@0 | 1048 | name: "I.1", |
michael@0 | 1049 | desc: "Remove unused keywords", |
michael@0 | 1050 | |
michael@0 | 1051 | _bookmarkId: null, |
michael@0 | 1052 | _placeId: null, |
michael@0 | 1053 | |
michael@0 | 1054 | setup: function() { |
michael@0 | 1055 | // Insert 2 keywords |
michael@0 | 1056 | let stmt = mDBConn.createStatement("INSERT INTO moz_keywords (id, keyword) VALUES(:id, :keyword)"); |
michael@0 | 1057 | stmt.params["id"] = 1; |
michael@0 | 1058 | stmt.params["keyword"] = "used"; |
michael@0 | 1059 | stmt.execute(); |
michael@0 | 1060 | stmt.reset(); |
michael@0 | 1061 | stmt.params["id"] = 2; |
michael@0 | 1062 | stmt.params["keyword"] = "unused"; |
michael@0 | 1063 | stmt.execute(); |
michael@0 | 1064 | stmt.finalize(); |
michael@0 | 1065 | // Add a place to ensure place_id = 1 is valid |
michael@0 | 1066 | this._placeId = addPlace(); |
michael@0 | 1067 | // Insert a bookmark using the "used" keyword |
michael@0 | 1068 | this._bookmarkId = addBookmark(this._placeId, bs.TYPE_BOOKMARK, bs.unfiledBookmarksFolder, 1); |
michael@0 | 1069 | }, |
michael@0 | 1070 | |
michael@0 | 1071 | check: function() { |
michael@0 | 1072 | // Check that "used" keyword is still there |
michael@0 | 1073 | let stmt = mDBConn.createStatement("SELECT id FROM moz_keywords WHERE keyword = :keyword"); |
michael@0 | 1074 | stmt.params["keyword"] = "used"; |
michael@0 | 1075 | do_check_true(stmt.executeStep()); |
michael@0 | 1076 | stmt.reset(); |
michael@0 | 1077 | // Check that "unused" keyword has gone |
michael@0 | 1078 | stmt.params["keyword"] = "unused"; |
michael@0 | 1079 | do_check_false(stmt.executeStep()); |
michael@0 | 1080 | stmt.finalize(); |
michael@0 | 1081 | } |
michael@0 | 1082 | }); |
michael@0 | 1083 | |
michael@0 | 1084 | |
michael@0 | 1085 | //------------------------------------------------------------------------------ |
michael@0 | 1086 | |
michael@0 | 1087 | tests.push({ |
michael@0 | 1088 | name: "L.1", |
michael@0 | 1089 | desc: "Fix wrong favicon ids", |
michael@0 | 1090 | |
michael@0 | 1091 | _validIconPlaceId: null, |
michael@0 | 1092 | _invalidIconPlaceId: null, |
michael@0 | 1093 | |
michael@0 | 1094 | setup: function() { |
michael@0 | 1095 | // Insert a favicon entry |
michael@0 | 1096 | let stmt = mDBConn.createStatement("INSERT INTO moz_favicons (id, url) VALUES(1, :url)"); |
michael@0 | 1097 | stmt.params["url"] = "http://www.mozilla.org/favicon.ico"; |
michael@0 | 1098 | stmt.execute(); |
michael@0 | 1099 | stmt.finalize(); |
michael@0 | 1100 | // Insert a place using the existing favicon entry |
michael@0 | 1101 | this._validIconPlaceId = addPlace("http://www1.mozilla.org", 1); |
michael@0 | 1102 | |
michael@0 | 1103 | // Insert a place using a nonexistent favicon entry |
michael@0 | 1104 | this._invalidIconPlaceId = addPlace("http://www2.mozilla.org", 1337); |
michael@0 | 1105 | }, |
michael@0 | 1106 | |
michael@0 | 1107 | check: function() { |
michael@0 | 1108 | // Check that bogus favicon is not there |
michael@0 | 1109 | let stmt = mDBConn.createStatement("SELECT id FROM moz_places WHERE favicon_id = :favicon_id"); |
michael@0 | 1110 | stmt.params["favicon_id"] = 1337; |
michael@0 | 1111 | do_check_false(stmt.executeStep()); |
michael@0 | 1112 | stmt.reset(); |
michael@0 | 1113 | // Check that valid favicon is still there |
michael@0 | 1114 | stmt.params["favicon_id"] = 1; |
michael@0 | 1115 | do_check_true(stmt.executeStep()); |
michael@0 | 1116 | stmt.finalize(); |
michael@0 | 1117 | // Check that place entries are there |
michael@0 | 1118 | stmt = mDBConn.createStatement("SELECT id FROM moz_places WHERE id = :place_id"); |
michael@0 | 1119 | stmt.params["place_id"] = this._validIconPlaceId; |
michael@0 | 1120 | do_check_true(stmt.executeStep()); |
michael@0 | 1121 | stmt.reset(); |
michael@0 | 1122 | stmt.params["place_id"] = this._invalidIconPlaceId; |
michael@0 | 1123 | do_check_true(stmt.executeStep()); |
michael@0 | 1124 | stmt.finalize(); |
michael@0 | 1125 | } |
michael@0 | 1126 | }); |
michael@0 | 1127 | |
michael@0 | 1128 | //------------------------------------------------------------------------------ |
michael@0 | 1129 | |
michael@0 | 1130 | tests.push({ |
michael@0 | 1131 | name: "L.2", |
michael@0 | 1132 | desc: "Recalculate visit_count and last_visit_date", |
michael@0 | 1133 | |
michael@0 | 1134 | setup: function() { |
michael@0 | 1135 | function setVisitCount(aURL, aValue) { |
michael@0 | 1136 | let stmt = mDBConn.createStatement( |
michael@0 | 1137 | "UPDATE moz_places SET visit_count = :count WHERE url = :url" |
michael@0 | 1138 | ); |
michael@0 | 1139 | stmt.params.count = aValue; |
michael@0 | 1140 | stmt.params.url = aURL; |
michael@0 | 1141 | stmt.execute(); |
michael@0 | 1142 | stmt.finalize(); |
michael@0 | 1143 | } |
michael@0 | 1144 | function setLastVisitDate(aURL, aValue) { |
michael@0 | 1145 | let stmt = mDBConn.createStatement( |
michael@0 | 1146 | "UPDATE moz_places SET last_visit_date = :date WHERE url = :url" |
michael@0 | 1147 | ); |
michael@0 | 1148 | stmt.params.date = aValue; |
michael@0 | 1149 | stmt.params.url = aURL; |
michael@0 | 1150 | stmt.execute(); |
michael@0 | 1151 | stmt.finalize(); |
michael@0 | 1152 | } |
michael@0 | 1153 | |
michael@0 | 1154 | let now = Date.now() * 1000; |
michael@0 | 1155 | // Add a page with 1 visit. |
michael@0 | 1156 | let url = "http://1.moz.org/"; |
michael@0 | 1157 | yield promiseAddVisits({ uri: uri(url), visitDate: now++ }); |
michael@0 | 1158 | // Add a page with 1 visit and set wrong visit_count. |
michael@0 | 1159 | url = "http://2.moz.org/"; |
michael@0 | 1160 | yield promiseAddVisits({ uri: uri(url), visitDate: now++ }); |
michael@0 | 1161 | setVisitCount(url, 10); |
michael@0 | 1162 | // Add a page with 1 visit and set wrong last_visit_date. |
michael@0 | 1163 | url = "http://3.moz.org/"; |
michael@0 | 1164 | yield promiseAddVisits({ uri: uri(url), visitDate: now++ }); |
michael@0 | 1165 | setLastVisitDate(url, now++); |
michael@0 | 1166 | // Add a page with 1 visit and set wrong stats. |
michael@0 | 1167 | url = "http://4.moz.org/"; |
michael@0 | 1168 | yield promiseAddVisits({ uri: uri(url), visitDate: now++ }); |
michael@0 | 1169 | setVisitCount(url, 10); |
michael@0 | 1170 | setLastVisitDate(url, now++); |
michael@0 | 1171 | |
michael@0 | 1172 | // Add a page without visits. |
michael@0 | 1173 | let url = "http://5.moz.org/"; |
michael@0 | 1174 | addPlace(url); |
michael@0 | 1175 | // Add a page without visits and set wrong visit_count. |
michael@0 | 1176 | url = "http://6.moz.org/"; |
michael@0 | 1177 | addPlace(url); |
michael@0 | 1178 | setVisitCount(url, 10); |
michael@0 | 1179 | // Add a page without visits and set wrong last_visit_date. |
michael@0 | 1180 | url = "http://7.moz.org/"; |
michael@0 | 1181 | addPlace(url); |
michael@0 | 1182 | setLastVisitDate(url, now++); |
michael@0 | 1183 | // Add a page without visits and set wrong stats. |
michael@0 | 1184 | url = "http://8.moz.org/"; |
michael@0 | 1185 | addPlace(url); |
michael@0 | 1186 | setVisitCount(url, 10); |
michael@0 | 1187 | setLastVisitDate(url, now++); |
michael@0 | 1188 | }, |
michael@0 | 1189 | |
michael@0 | 1190 | check: function() { |
michael@0 | 1191 | let stmt = mDBConn.createStatement( |
michael@0 | 1192 | "SELECT h.id FROM moz_places h " + |
michael@0 | 1193 | "JOIN moz_historyvisits v ON v.place_id = h.id AND visit_type NOT IN (0,4,7,8) " + |
michael@0 | 1194 | "GROUP BY h.id HAVING h.visit_count <> count(*) " + |
michael@0 | 1195 | "UNION ALL " + |
michael@0 | 1196 | "SELECT h.id FROM moz_places h " + |
michael@0 | 1197 | "JOIN moz_historyvisits v ON v.place_id = h.id " + |
michael@0 | 1198 | "GROUP BY h.id HAVING h.last_visit_date <> MAX(v.visit_date) " |
michael@0 | 1199 | ); |
michael@0 | 1200 | do_check_false(stmt.executeStep()); |
michael@0 | 1201 | stmt.finalize(); |
michael@0 | 1202 | } |
michael@0 | 1203 | }); |
michael@0 | 1204 | |
michael@0 | 1205 | //------------------------------------------------------------------------------ |
michael@0 | 1206 | |
michael@0 | 1207 | tests.push({ |
michael@0 | 1208 | name: "L.3", |
michael@0 | 1209 | desc: "recalculate hidden for redirects.", |
michael@0 | 1210 | |
michael@0 | 1211 | setup: function() { |
michael@0 | 1212 | promiseAddVisits([ |
michael@0 | 1213 | { uri: NetUtil.newURI("http://l3.moz.org/"), |
michael@0 | 1214 | transition: TRANSITION_TYPED }, |
michael@0 | 1215 | { uri: NetUtil.newURI("http://l3.moz.org/redirecting/"), |
michael@0 | 1216 | transition: TRANSITION_TYPED }, |
michael@0 | 1217 | { uri: NetUtil.newURI("http://l3.moz.org/redirecting2/"), |
michael@0 | 1218 | transition: TRANSITION_REDIRECT_TEMPORARY, |
michael@0 | 1219 | referrer: NetUtil.newURI("http://l3.moz.org/redirecting/") }, |
michael@0 | 1220 | { uri: NetUtil.newURI("http://l3.moz.org/target/"), |
michael@0 | 1221 | transition: TRANSITION_REDIRECT_PERMANENT, |
michael@0 | 1222 | referrer: NetUtil.newURI("http://l3.moz.org/redirecting2/") }, |
michael@0 | 1223 | ]); |
michael@0 | 1224 | }, |
michael@0 | 1225 | |
michael@0 | 1226 | asyncCheck: function(aCallback) { |
michael@0 | 1227 | let stmt = mDBConn.createAsyncStatement( |
michael@0 | 1228 | "SELECT h.url FROM moz_places h WHERE h.hidden = 1" |
michael@0 | 1229 | ); |
michael@0 | 1230 | stmt.executeAsync({ |
michael@0 | 1231 | _count: 0, |
michael@0 | 1232 | handleResult: function(aResultSet) { |
michael@0 | 1233 | for (let row; (row = aResultSet.getNextRow());) { |
michael@0 | 1234 | let url = row.getResultByIndex(0); |
michael@0 | 1235 | do_check_true(/redirecting/.test(url)); |
michael@0 | 1236 | this._count++; |
michael@0 | 1237 | } |
michael@0 | 1238 | }, |
michael@0 | 1239 | handleError: function(aError) { |
michael@0 | 1240 | }, |
michael@0 | 1241 | handleCompletion: function(aReason) { |
michael@0 | 1242 | dump_table("moz_places"); |
michael@0 | 1243 | dump_table("moz_historyvisits"); |
michael@0 | 1244 | do_check_eq(aReason, Ci.mozIStorageStatementCallback.REASON_FINISHED); |
michael@0 | 1245 | do_check_eq(this._count, 2); |
michael@0 | 1246 | aCallback(); |
michael@0 | 1247 | } |
michael@0 | 1248 | }); |
michael@0 | 1249 | stmt.finalize(); |
michael@0 | 1250 | } |
michael@0 | 1251 | }); |
michael@0 | 1252 | |
michael@0 | 1253 | //------------------------------------------------------------------------------ |
michael@0 | 1254 | |
michael@0 | 1255 | tests.push({ |
michael@0 | 1256 | name: "Z", |
michael@0 | 1257 | desc: "Sanity: Preventive maintenance does not touch valid items", |
michael@0 | 1258 | |
michael@0 | 1259 | _uri1: uri("http://www1.mozilla.org"), |
michael@0 | 1260 | _uri2: uri("http://www2.mozilla.org"), |
michael@0 | 1261 | _folderId: null, |
michael@0 | 1262 | _bookmarkId: null, |
michael@0 | 1263 | _separatorId: null, |
michael@0 | 1264 | |
michael@0 | 1265 | setup: function() { |
michael@0 | 1266 | // use valid api calls to create a bunch of items |
michael@0 | 1267 | yield promiseAddVisits([ |
michael@0 | 1268 | { uri: this._uri1 }, |
michael@0 | 1269 | { uri: this._uri2 }, |
michael@0 | 1270 | ]); |
michael@0 | 1271 | |
michael@0 | 1272 | this._folderId = bs.createFolder(bs.toolbarFolder, "testfolder", |
michael@0 | 1273 | bs.DEFAULT_INDEX); |
michael@0 | 1274 | do_check_true(this._folderId > 0); |
michael@0 | 1275 | this._bookmarkId = bs.insertBookmark(this._folderId, this._uri1, |
michael@0 | 1276 | bs.DEFAULT_INDEX, "testbookmark"); |
michael@0 | 1277 | do_check_true(this._bookmarkId > 0); |
michael@0 | 1278 | this._separatorId = bs.insertSeparator(bs.unfiledBookmarksFolder, |
michael@0 | 1279 | bs.DEFAULT_INDEX); |
michael@0 | 1280 | do_check_true(this._separatorId > 0); |
michael@0 | 1281 | ts.tagURI(this._uri1, ["testtag"]); |
michael@0 | 1282 | fs.setAndFetchFaviconForPage(this._uri2, SMALLPNG_DATA_URI, false, |
michael@0 | 1283 | PlacesUtils.favicons.FAVICON_LOAD_NON_PRIVATE); |
michael@0 | 1284 | bs.setKeywordForBookmark(this._bookmarkId, "testkeyword"); |
michael@0 | 1285 | as.setPageAnnotation(this._uri2, "anno", "anno", 0, as.EXPIRE_NEVER); |
michael@0 | 1286 | as.setItemAnnotation(this._bookmarkId, "anno", "anno", 0, as.EXPIRE_NEVER); |
michael@0 | 1287 | }, |
michael@0 | 1288 | |
michael@0 | 1289 | asyncCheck: function (aCallback) { |
michael@0 | 1290 | // Check that all items are correct |
michael@0 | 1291 | PlacesUtils.asyncHistory.isURIVisited(this._uri1, function(aURI, aIsVisited) { |
michael@0 | 1292 | do_check_true(aIsVisited); |
michael@0 | 1293 | PlacesUtils.asyncHistory.isURIVisited(this._uri2, function(aURI, aIsVisited) { |
michael@0 | 1294 | do_check_true(aIsVisited); |
michael@0 | 1295 | |
michael@0 | 1296 | do_check_eq(bs.getBookmarkURI(this._bookmarkId).spec, this._uri1.spec); |
michael@0 | 1297 | do_check_eq(bs.getItemIndex(this._folderId), 0); |
michael@0 | 1298 | |
michael@0 | 1299 | do_check_eq(bs.getItemType(this._folderId), bs.TYPE_FOLDER); |
michael@0 | 1300 | do_check_eq(bs.getItemType(this._separatorId), bs.TYPE_SEPARATOR); |
michael@0 | 1301 | |
michael@0 | 1302 | do_check_eq(ts.getTagsForURI(this._uri1).length, 1); |
michael@0 | 1303 | do_check_eq(bs.getKeywordForBookmark(this._bookmarkId), "testkeyword"); |
michael@0 | 1304 | do_check_eq(as.getPageAnnotation(this._uri2, "anno"), "anno"); |
michael@0 | 1305 | do_check_eq(as.getItemAnnotation(this._bookmarkId, "anno"), "anno"); |
michael@0 | 1306 | |
michael@0 | 1307 | fs.getFaviconURLForPage(this._uri2, function (aFaviconURI) { |
michael@0 | 1308 | do_check_true(aFaviconURI.equals(SMALLPNG_DATA_URI)); |
michael@0 | 1309 | aCallback(); |
michael@0 | 1310 | }); |
michael@0 | 1311 | }.bind(this)); |
michael@0 | 1312 | }.bind(this)); |
michael@0 | 1313 | } |
michael@0 | 1314 | }); |
michael@0 | 1315 | |
michael@0 | 1316 | //------------------------------------------------------------------------------ |
michael@0 | 1317 | |
michael@0 | 1318 | // main |
michael@0 | 1319 | function run_test() |
michael@0 | 1320 | { |
michael@0 | 1321 | run_next_test(); |
michael@0 | 1322 | } |
michael@0 | 1323 | |
michael@0 | 1324 | add_task(function test_preventive_maintenance() |
michael@0 | 1325 | { |
michael@0 | 1326 | // Force initialization of the bookmarks hash. This test could cause |
michael@0 | 1327 | // it to go out of sync due to direct queries on the database. |
michael@0 | 1328 | yield promiseAddVisits(uri("http://force.bookmarks.hash")); |
michael@0 | 1329 | do_check_false(bs.isBookmarked(uri("http://force.bookmarks.hash"))); |
michael@0 | 1330 | |
michael@0 | 1331 | // Get current bookmarks max ID for cleanup |
michael@0 | 1332 | let stmt = mDBConn.createStatement("SELECT MAX(id) FROM moz_bookmarks"); |
michael@0 | 1333 | stmt.executeStep(); |
michael@0 | 1334 | defaultBookmarksMaxId = stmt.getInt32(0); |
michael@0 | 1335 | stmt.finalize(); |
michael@0 | 1336 | do_check_true(defaultBookmarksMaxId > 0); |
michael@0 | 1337 | |
michael@0 | 1338 | for ([, test] in Iterator(tests)) { |
michael@0 | 1339 | dump("\nExecuting test: " + test.name + "\n" + "*** " + test.desc + "\n"); |
michael@0 | 1340 | yield test.setup(); |
michael@0 | 1341 | |
michael@0 | 1342 | let promiseMaintenanceFinished = |
michael@0 | 1343 | promiseTopicObserved(FINISHED_MAINTENANCE_NOTIFICATION_TOPIC); |
michael@0 | 1344 | PlacesDBUtils.maintenanceOnIdle(); |
michael@0 | 1345 | yield promiseMaintenanceFinished; |
michael@0 | 1346 | |
michael@0 | 1347 | // Check the lastMaintenance time has been saved. |
michael@0 | 1348 | do_check_neq(Services.prefs.getIntPref("places.database.lastMaintenance"), null); |
michael@0 | 1349 | |
michael@0 | 1350 | if (test.asyncCheck) { |
michael@0 | 1351 | let deferred = Promise.defer(); |
michael@0 | 1352 | test.asyncCheck(deferred.resolve); |
michael@0 | 1353 | yield deferred.promise; |
michael@0 | 1354 | } else { |
michael@0 | 1355 | test.check(); |
michael@0 | 1356 | } |
michael@0 | 1357 | |
michael@0 | 1358 | cleanDatabase(); |
michael@0 | 1359 | } |
michael@0 | 1360 | |
michael@0 | 1361 | // Sanity check: all roots should be intact |
michael@0 | 1362 | do_check_eq(bs.getFolderIdForItem(bs.placesRoot), 0); |
michael@0 | 1363 | do_check_eq(bs.getFolderIdForItem(bs.bookmarksMenuFolder), bs.placesRoot); |
michael@0 | 1364 | do_check_eq(bs.getFolderIdForItem(bs.tagsFolder), bs.placesRoot); |
michael@0 | 1365 | do_check_eq(bs.getFolderIdForItem(bs.unfiledBookmarksFolder), bs.placesRoot); |
michael@0 | 1366 | do_check_eq(bs.getFolderIdForItem(bs.toolbarFolder), bs.placesRoot); |
michael@0 | 1367 | }); |