michael@0: /* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ michael@0: /* vim:set ts=2 sw=2 sts=2 et: */ michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: let bs = PlacesUtils.bookmarks; michael@0: let hs = PlacesUtils.history; michael@0: let anno = PlacesUtils.annotations; michael@0: michael@0: michael@0: let bookmarksObserver = { michael@0: onBeginUpdateBatch: function() { michael@0: this._beginUpdateBatch = true; michael@0: }, michael@0: onEndUpdateBatch: function() { michael@0: this._endUpdateBatch = true; michael@0: }, michael@0: onItemAdded: function(id, folder, index, itemType, uri, title, dateAdded, michael@0: guid) { michael@0: this._itemAddedId = id; michael@0: this._itemAddedParent = folder; michael@0: this._itemAddedIndex = index; michael@0: this._itemAddedURI = uri; michael@0: this._itemAddedTitle = title; michael@0: michael@0: // Ensure that we've created a guid for this item. michael@0: let stmt = DBConn().createStatement( michael@0: "SELECT guid " michael@0: + "FROM moz_bookmarks " michael@0: + "WHERE id = :item_id " michael@0: ); michael@0: stmt.params.item_id = id; michael@0: do_check_true(stmt.executeStep()); michael@0: do_check_false(stmt.getIsNull(0)); michael@0: do_check_valid_places_guid(stmt.row.guid); michael@0: do_check_eq(stmt.row.guid, guid); michael@0: stmt.finalize(); michael@0: }, michael@0: onItemRemoved: function(id, folder, index, itemType) { michael@0: this._itemRemovedId = id; michael@0: this._itemRemovedFolder = folder; michael@0: this._itemRemovedIndex = index; michael@0: }, michael@0: onItemChanged: function(id, property, isAnnotationProperty, value, michael@0: lastModified, itemType) { michael@0: this._itemChangedId = id; michael@0: this._itemChangedProperty = property; michael@0: this._itemChanged_isAnnotationProperty = isAnnotationProperty; michael@0: this._itemChangedValue = value; michael@0: }, michael@0: onItemVisited: function(id, visitID, time) { michael@0: this._itemVisitedId = id; michael@0: this._itemVisitedVistId = visitID; michael@0: this._itemVisitedTime = time; michael@0: }, michael@0: onItemMoved: function(id, oldParent, oldIndex, newParent, newIndex, michael@0: itemType) { michael@0: this._itemMovedId = id michael@0: this._itemMovedOldParent = oldParent; michael@0: this._itemMovedOldIndex = oldIndex; michael@0: this._itemMovedNewParent = newParent; michael@0: this._itemMovedNewIndex = newIndex; michael@0: }, michael@0: QueryInterface: XPCOMUtils.generateQI([ michael@0: Ci.nsINavBookmarkObserver, michael@0: ]) michael@0: }; michael@0: michael@0: michael@0: // Get bookmarks menu folder id. michael@0: let root = bs.bookmarksMenuFolder; michael@0: // Index at which items should begin. michael@0: let bmStartIndex = 0; michael@0: michael@0: michael@0: function run_test() { michael@0: run_next_test(); michael@0: } michael@0: michael@0: add_task(function test_bookmarks() { michael@0: bs.addObserver(bookmarksObserver, false); michael@0: michael@0: // test special folders michael@0: do_check_true(bs.placesRoot > 0); michael@0: do_check_true(bs.bookmarksMenuFolder > 0); michael@0: do_check_true(bs.tagsFolder > 0); michael@0: do_check_true(bs.toolbarFolder > 0); michael@0: do_check_true(bs.unfiledBookmarksFolder > 0); michael@0: michael@0: // test getFolderIdForItem() with bogus item id will throw michael@0: try { michael@0: let id = bs.getFolderIdForItem(0); michael@0: do_throw("getFolderIdForItem accepted bad input"); michael@0: } catch(ex) {} michael@0: michael@0: // test getFolderIdForItem() with bogus item id will throw michael@0: try { michael@0: let id = bs.getFolderIdForItem(-1); michael@0: do_throw("getFolderIdForItem accepted bad input"); michael@0: } catch(ex) {} michael@0: michael@0: // test root parentage michael@0: do_check_eq(bs.getFolderIdForItem(bs.bookmarksMenuFolder), bs.placesRoot); michael@0: do_check_eq(bs.getFolderIdForItem(bs.tagsFolder), bs.placesRoot); michael@0: do_check_eq(bs.getFolderIdForItem(bs.toolbarFolder), bs.placesRoot); michael@0: do_check_eq(bs.getFolderIdForItem(bs.unfiledBookmarksFolder), bs.placesRoot); michael@0: michael@0: // create a folder to hold all the tests michael@0: // this makes the tests more tolerant of changes to default_places.html michael@0: let testRoot = bs.createFolder(root, "places bookmarks xpcshell tests", michael@0: bs.DEFAULT_INDEX); michael@0: do_check_eq(bookmarksObserver._itemAddedId, testRoot); michael@0: do_check_eq(bookmarksObserver._itemAddedParent, root); michael@0: do_check_eq(bookmarksObserver._itemAddedIndex, bmStartIndex); michael@0: do_check_eq(bookmarksObserver._itemAddedURI, null); michael@0: let testStartIndex = 0; michael@0: michael@0: // test getItemIndex for folders michael@0: do_check_eq(bs.getItemIndex(testRoot), bmStartIndex); michael@0: michael@0: // test getItemType for folders michael@0: do_check_eq(bs.getItemType(testRoot), bs.TYPE_FOLDER); michael@0: michael@0: // insert a bookmark. michael@0: // the time before we insert, in microseconds michael@0: let beforeInsert = Date.now() * 1000; michael@0: do_check_true(beforeInsert > 0); michael@0: michael@0: let newId = bs.insertBookmark(testRoot, uri("http://google.com/"), michael@0: bs.DEFAULT_INDEX, ""); michael@0: do_check_eq(bookmarksObserver._itemAddedId, newId); michael@0: do_check_eq(bookmarksObserver._itemAddedParent, testRoot); michael@0: do_check_eq(bookmarksObserver._itemAddedIndex, testStartIndex); michael@0: do_check_true(bookmarksObserver._itemAddedURI.equals(uri("http://google.com/"))); michael@0: do_check_eq(bs.getBookmarkURI(newId).spec, "http://google.com/"); michael@0: michael@0: let dateAdded = bs.getItemDateAdded(newId); michael@0: // dateAdded can equal beforeInsert michael@0: do_check_true(is_time_ordered(beforeInsert, dateAdded)); michael@0: michael@0: // after just inserting, modified should not be set michael@0: let lastModified = bs.getItemLastModified(newId); michael@0: do_check_eq(lastModified, dateAdded); michael@0: michael@0: // The time before we set the title, in microseconds. michael@0: let beforeSetTitle = Date.now() * 1000; michael@0: do_check_true(beforeSetTitle >= beforeInsert); michael@0: michael@0: // Workaround possible VM timers issues moving lastModified and dateAdded michael@0: // to the past. michael@0: bs.setItemLastModified(newId, --lastModified); michael@0: bs.setItemDateAdded(newId, --dateAdded); michael@0: michael@0: // set bookmark title michael@0: bs.setItemTitle(newId, "Google"); michael@0: do_check_eq(bookmarksObserver._itemChangedId, newId); michael@0: do_check_eq(bookmarksObserver._itemChangedProperty, "title"); michael@0: do_check_eq(bookmarksObserver._itemChangedValue, "Google"); michael@0: michael@0: // check that dateAdded hasn't changed michael@0: let dateAdded2 = bs.getItemDateAdded(newId); michael@0: do_check_eq(dateAdded2, dateAdded); michael@0: michael@0: // check lastModified after we set the title michael@0: let lastModified2 = bs.getItemLastModified(newId); michael@0: LOG("test setItemTitle"); michael@0: LOG("dateAdded = " + dateAdded); michael@0: LOG("beforeSetTitle = " + beforeSetTitle); michael@0: LOG("lastModified = " + lastModified); michael@0: LOG("lastModified2 = " + lastModified2); michael@0: do_check_true(is_time_ordered(lastModified, lastModified2)); michael@0: do_check_true(is_time_ordered(dateAdded, lastModified2)); michael@0: michael@0: // get item title michael@0: let title = bs.getItemTitle(newId); michael@0: do_check_eq(title, "Google"); michael@0: michael@0: // test getItemType for bookmarks michael@0: do_check_eq(bs.getItemType(newId), bs.TYPE_BOOKMARK); michael@0: michael@0: // get item title bad input michael@0: try { michael@0: let title = bs.getItemTitle(-3); michael@0: do_throw("getItemTitle accepted bad input"); michael@0: } catch(ex) {} michael@0: michael@0: // get the folder that the bookmark is in michael@0: let folderId = bs.getFolderIdForItem(newId); michael@0: do_check_eq(folderId, testRoot); michael@0: michael@0: // test getItemIndex for bookmarks michael@0: do_check_eq(bs.getItemIndex(newId), testStartIndex); michael@0: michael@0: // create a folder at a specific index michael@0: let workFolder = bs.createFolder(testRoot, "Work", 0); michael@0: do_check_eq(bookmarksObserver._itemAddedId, workFolder); michael@0: do_check_eq(bookmarksObserver._itemAddedParent, testRoot); michael@0: do_check_eq(bookmarksObserver._itemAddedIndex, 0); michael@0: do_check_eq(bookmarksObserver._itemAddedURI, null); michael@0: michael@0: do_check_eq(bs.getItemTitle(workFolder), "Work"); michael@0: bs.setItemTitle(workFolder, "Work #"); michael@0: do_check_eq(bs.getItemTitle(workFolder), "Work #"); michael@0: michael@0: // add item into subfolder, specifying index michael@0: let newId2 = bs.insertBookmark(workFolder, michael@0: uri("http://developer.mozilla.org/"), michael@0: 0, ""); michael@0: do_check_eq(bookmarksObserver._itemAddedId, newId2); michael@0: do_check_eq(bookmarksObserver._itemAddedParent, workFolder); michael@0: do_check_eq(bookmarksObserver._itemAddedIndex, 0); michael@0: michael@0: // change item michael@0: bs.setItemTitle(newId2, "DevMo"); michael@0: do_check_eq(bookmarksObserver._itemChangedProperty, "title"); michael@0: michael@0: // insert item into subfolder michael@0: let newId3 = bs.insertBookmark(workFolder, michael@0: uri("http://msdn.microsoft.com/"), michael@0: bs.DEFAULT_INDEX, ""); michael@0: do_check_eq(bookmarksObserver._itemAddedId, newId3); michael@0: do_check_eq(bookmarksObserver._itemAddedParent, workFolder); michael@0: do_check_eq(bookmarksObserver._itemAddedIndex, 1); michael@0: michael@0: // change item michael@0: bs.setItemTitle(newId3, "MSDN"); michael@0: do_check_eq(bookmarksObserver._itemChangedProperty, "title"); michael@0: michael@0: // remove item michael@0: bs.removeItem(newId2); michael@0: do_check_eq(bookmarksObserver._itemRemovedId, newId2); michael@0: do_check_eq(bookmarksObserver._itemRemovedFolder, workFolder); michael@0: do_check_eq(bookmarksObserver._itemRemovedIndex, 0); michael@0: michael@0: // insert item into subfolder michael@0: let newId4 = bs.insertBookmark(workFolder, michael@0: uri("http://developer.mozilla.org/"), michael@0: bs.DEFAULT_INDEX, ""); michael@0: do_check_eq(bookmarksObserver._itemAddedId, newId4); michael@0: do_check_eq(bookmarksObserver._itemAddedParent, workFolder); michael@0: do_check_eq(bookmarksObserver._itemAddedIndex, 1); michael@0: michael@0: // create folder michael@0: let homeFolder = bs.createFolder(testRoot, "Home", bs.DEFAULT_INDEX); michael@0: do_check_eq(bookmarksObserver._itemAddedId, homeFolder); michael@0: do_check_eq(bookmarksObserver._itemAddedParent, testRoot); michael@0: do_check_eq(bookmarksObserver._itemAddedIndex, 2); michael@0: michael@0: // insert item michael@0: let newId5 = bs.insertBookmark(homeFolder, uri("http://espn.com/"), michael@0: bs.DEFAULT_INDEX, ""); michael@0: do_check_eq(bookmarksObserver._itemAddedId, newId5); michael@0: do_check_eq(bookmarksObserver._itemAddedParent, homeFolder); michael@0: do_check_eq(bookmarksObserver._itemAddedIndex, 0); michael@0: michael@0: // change item michael@0: bs.setItemTitle(newId5, "ESPN"); michael@0: do_check_eq(bookmarksObserver._itemChangedId, newId5); michael@0: do_check_eq(bookmarksObserver._itemChangedProperty, "title"); michael@0: michael@0: // insert query item michael@0: let uri6 = uri("place:domain=google.com&type="+ michael@0: Ci.nsINavHistoryQueryOptions.RESULTS_AS_SITE_QUERY); michael@0: let newId6 = bs.insertBookmark(testRoot, uri6, bs.DEFAULT_INDEX, ""); michael@0: do_check_eq(bookmarksObserver._itemAddedParent, testRoot); michael@0: do_check_eq(bookmarksObserver._itemAddedIndex, 3); michael@0: michael@0: // change item michael@0: bs.setItemTitle(newId6, "Google Sites"); michael@0: do_check_eq(bookmarksObserver._itemChangedProperty, "title"); michael@0: michael@0: // test getIdForItemAt michael@0: do_check_eq(bs.getIdForItemAt(testRoot, 0), workFolder); michael@0: // wrong parent, should return -1 michael@0: do_check_eq(bs.getIdForItemAt(1337, 0), -1); michael@0: // wrong index, should return -1 michael@0: do_check_eq(bs.getIdForItemAt(testRoot, 1337), -1); michael@0: // wrong parent and index, should return -1 michael@0: do_check_eq(bs.getIdForItemAt(1337, 1337), -1); michael@0: michael@0: // move folder, appending, to different folder michael@0: let oldParentCC = getChildCount(testRoot); michael@0: bs.moveItem(workFolder, homeFolder, bs.DEFAULT_INDEX); michael@0: do_check_eq(bookmarksObserver._itemMovedId, workFolder); michael@0: do_check_eq(bookmarksObserver._itemMovedOldParent, testRoot); michael@0: do_check_eq(bookmarksObserver._itemMovedOldIndex, 0); michael@0: do_check_eq(bookmarksObserver._itemMovedNewParent, homeFolder); michael@0: do_check_eq(bookmarksObserver._itemMovedNewIndex, 1); michael@0: michael@0: // test that the new index is properly stored michael@0: do_check_eq(bs.getItemIndex(workFolder), 1); michael@0: do_check_eq(bs.getFolderIdForItem(workFolder), homeFolder); michael@0: michael@0: // try to get index of the item from within the old parent folder michael@0: // check that it has been really removed from there michael@0: do_check_neq(bs.getIdForItemAt(testRoot, 0), workFolder); michael@0: // check the last item from within the old parent folder michael@0: do_check_neq(bs.getIdForItemAt(testRoot, -1), workFolder); michael@0: // check the index of the item within the new parent folder michael@0: do_check_eq(bs.getIdForItemAt(homeFolder, 1), workFolder); michael@0: // try to get index of the last item within the new parent folder michael@0: do_check_eq(bs.getIdForItemAt(homeFolder, -1), workFolder); michael@0: // XXX expose FolderCount, and check that the old parent has one less child? michael@0: do_check_eq(getChildCount(testRoot), oldParentCC-1); michael@0: michael@0: // move item, appending, to different folder michael@0: bs.moveItem(newId5, testRoot, bs.DEFAULT_INDEX); michael@0: do_check_eq(bookmarksObserver._itemMovedId, newId5); michael@0: do_check_eq(bookmarksObserver._itemMovedOldParent, homeFolder); michael@0: do_check_eq(bookmarksObserver._itemMovedOldIndex, 0); michael@0: do_check_eq(bookmarksObserver._itemMovedNewParent, testRoot); michael@0: do_check_eq(bookmarksObserver._itemMovedNewIndex, 3); michael@0: michael@0: // test get folder's index michael@0: let tmpFolder = bs.createFolder(testRoot, "tmp", 2); michael@0: do_check_eq(bs.getItemIndex(tmpFolder), 2); michael@0: michael@0: // test setKeywordForBookmark michael@0: let kwTestItemId = bs.insertBookmark(testRoot, uri("http://keywordtest.com"), michael@0: bs.DEFAULT_INDEX, ""); michael@0: try { michael@0: let dateAdded = bs.getItemDateAdded(kwTestItemId); michael@0: // after just inserting, modified should not be set michael@0: let lastModified = bs.getItemLastModified(kwTestItemId); michael@0: do_check_eq(lastModified, dateAdded); michael@0: michael@0: // Workaround possible VM timers issues moving lastModified and dateAdded michael@0: // to the past. michael@0: bs.setItemLastModified(kwTestItemId, --lastModified); michael@0: bs.setItemDateAdded(kwTestItemId, --dateAdded); michael@0: michael@0: bs.setKeywordForBookmark(kwTestItemId, "bar"); michael@0: michael@0: let lastModified2 = bs.getItemLastModified(kwTestItemId); michael@0: LOG("test setKeywordForBookmark"); michael@0: LOG("dateAdded = " + dateAdded); michael@0: LOG("lastModified = " + lastModified); michael@0: LOG("lastModified2 = " + lastModified2); michael@0: do_check_true(is_time_ordered(lastModified, lastModified2)); michael@0: do_check_true(is_time_ordered(dateAdded, lastModified2)); michael@0: } catch(ex) { michael@0: do_throw("setKeywordForBookmark: " + ex); michael@0: } michael@0: michael@0: let lastModified3 = bs.getItemLastModified(kwTestItemId); michael@0: // test getKeywordForBookmark michael@0: let k = bs.getKeywordForBookmark(kwTestItemId); michael@0: do_check_eq("bar", k); michael@0: michael@0: // test getKeywordForURI michael@0: let k = bs.getKeywordForURI(uri("http://keywordtest.com/")); michael@0: do_check_eq("bar", k); michael@0: michael@0: // test getURIForKeyword michael@0: let u = bs.getURIForKeyword("bar"); michael@0: do_check_eq("http://keywordtest.com/", u.spec); michael@0: michael@0: // test removeFolderChildren michael@0: // 1) add/remove each child type (bookmark, separator, folder) michael@0: let tmpFolder = bs.createFolder(testRoot, "removeFolderChildren", michael@0: bs.DEFAULT_INDEX); michael@0: bs.insertBookmark(tmpFolder, uri("http://foo9.com/"), bs.DEFAULT_INDEX, ""); michael@0: bs.createFolder(tmpFolder, "subfolder", bs.DEFAULT_INDEX); michael@0: bs.insertSeparator(tmpFolder, bs.DEFAULT_INDEX); michael@0: // 2) confirm that folder has 3 children michael@0: let options = hs.getNewQueryOptions(); michael@0: let query = hs.getNewQuery(); michael@0: query.setFolders([tmpFolder], 1); michael@0: try { michael@0: let result = hs.executeQuery(query, options); michael@0: let rootNode = result.root; michael@0: rootNode.containerOpen = true; michael@0: do_check_eq(rootNode.childCount, 3); michael@0: rootNode.containerOpen = false; michael@0: } catch(ex) { michael@0: do_throw("test removeFolderChildren() - querying for children failed: " + ex); michael@0: } michael@0: // 3) remove all children michael@0: bs.removeFolderChildren(tmpFolder); michael@0: // 4) confirm that folder has 0 children michael@0: try { michael@0: result = hs.executeQuery(query, options); michael@0: let rootNode = result.root; michael@0: rootNode.containerOpen = true; michael@0: do_check_eq(rootNode.childCount, 0); michael@0: rootNode.containerOpen = false; michael@0: } catch(ex) { michael@0: do_throw("removeFolderChildren(): " + ex); michael@0: } michael@0: michael@0: // XXX - test folderReadOnly michael@0: michael@0: // test bookmark id in query output michael@0: try { michael@0: let options = hs.getNewQueryOptions(); michael@0: let query = hs.getNewQuery(); michael@0: query.setFolders([testRoot], 1); michael@0: let result = hs.executeQuery(query, options); michael@0: let rootNode = result.root; michael@0: rootNode.containerOpen = true; michael@0: let cc = rootNode.childCount; michael@0: LOG("bookmark itemId test: CC = " + cc); michael@0: do_check_true(cc > 0); michael@0: for (let i=0; i < cc; ++i) { michael@0: let node = rootNode.getChild(i); michael@0: if (node.type == node.RESULT_TYPE_FOLDER || michael@0: node.type == node.RESULT_TYPE_URI || michael@0: node.type == node.RESULT_TYPE_SEPARATOR || michael@0: node.type == node.RESULT_TYPE_QUERY) { michael@0: do_check_true(node.itemId > 0); michael@0: } michael@0: else { michael@0: do_check_eq(node.itemId, -1); michael@0: } michael@0: } michael@0: rootNode.containerOpen = false; michael@0: } michael@0: catch(ex) { michael@0: do_throw("bookmarks query: " + ex); michael@0: } michael@0: michael@0: // test that multiple bookmarks with same URI show up right in bookmark michael@0: // folder queries, todo: also to do for complex folder queries michael@0: try { michael@0: // test uri michael@0: let mURI = uri("http://multiple.uris.in.query"); michael@0: michael@0: let testFolder = bs.createFolder(testRoot, "test Folder", bs.DEFAULT_INDEX); michael@0: // add 2 bookmarks michael@0: bs.insertBookmark(testFolder, mURI, bs.DEFAULT_INDEX, "title 1"); michael@0: bs.insertBookmark(testFolder, mURI, bs.DEFAULT_INDEX, "title 2"); michael@0: michael@0: // query michael@0: let options = hs.getNewQueryOptions(); michael@0: let query = hs.getNewQuery(); michael@0: query.setFolders([testFolder], 1); michael@0: let result = hs.executeQuery(query, options); michael@0: let rootNode = result.root; michael@0: rootNode.containerOpen = true; michael@0: let cc = rootNode.childCount; michael@0: do_check_eq(cc, 2); michael@0: do_check_eq(rootNode.getChild(0).title, "title 1"); michael@0: do_check_eq(rootNode.getChild(1).title, "title 2"); michael@0: rootNode.containerOpen = false; michael@0: } michael@0: catch(ex) { michael@0: do_throw("bookmarks query: " + ex); michael@0: } michael@0: michael@0: // test change bookmark uri michael@0: let newId10 = bs.insertBookmark(testRoot, uri("http://foo10.com/"), michael@0: bs.DEFAULT_INDEX, ""); michael@0: let dateAdded = bs.getItemDateAdded(newId10); michael@0: // after just inserting, modified should not be set michael@0: let lastModified = bs.getItemLastModified(newId10); michael@0: do_check_eq(lastModified, dateAdded); michael@0: michael@0: // Workaround possible VM timers issues moving lastModified and dateAdded michael@0: // to the past. michael@0: bs.setItemLastModified(newId10, --lastModified); michael@0: bs.setItemDateAdded(newId10, --dateAdded); michael@0: michael@0: bs.changeBookmarkURI(newId10, uri("http://foo11.com/")); michael@0: michael@0: // check that lastModified is set after we change the bookmark uri michael@0: let lastModified2 = bs.getItemLastModified(newId10); michael@0: LOG("test changeBookmarkURI"); michael@0: LOG("dateAdded = " + dateAdded); michael@0: LOG("lastModified = " + lastModified); michael@0: LOG("lastModified2 = " + lastModified2); michael@0: do_check_true(is_time_ordered(lastModified, lastModified2)); michael@0: do_check_true(is_time_ordered(dateAdded, lastModified2)); michael@0: michael@0: do_check_eq(bookmarksObserver._itemChangedId, newId10); michael@0: do_check_eq(bookmarksObserver._itemChangedProperty, "uri"); michael@0: do_check_eq(bookmarksObserver._itemChangedValue, "http://foo11.com/"); michael@0: michael@0: // test getBookmarkURI michael@0: let newId11 = bs.insertBookmark(testRoot, uri("http://foo11.com/"), michael@0: bs.DEFAULT_INDEX, ""); michael@0: let bmURI = bs.getBookmarkURI(newId11); michael@0: do_check_eq("http://foo11.com/", bmURI.spec); michael@0: michael@0: // test getBookmarkURI with non-bookmark items michael@0: try { michael@0: bs.getBookmarkURI(testRoot); michael@0: do_throw("getBookmarkURI() should throw for non-bookmark items!"); michael@0: } catch(ex) {} michael@0: michael@0: // test getItemIndex michael@0: let newId12 = bs.insertBookmark(testRoot, uri("http://foo11.com/"), 1, ""); michael@0: let bmIndex = bs.getItemIndex(newId12); michael@0: do_check_eq(1, bmIndex); michael@0: michael@0: // insert a bookmark with title ZZZXXXYYY and then search for it. michael@0: // this test confirms that we can find bookmarks that we haven't visited michael@0: // (which are "hidden") and that we can find by title. michael@0: // see bug #369887 for more details michael@0: let newId13 = bs.insertBookmark(testRoot, uri("http://foobarcheese.com/"), michael@0: bs.DEFAULT_INDEX, ""); michael@0: do_check_eq(bookmarksObserver._itemAddedId, newId13); michael@0: do_check_eq(bookmarksObserver._itemAddedParent, testRoot); michael@0: do_check_eq(bookmarksObserver._itemAddedIndex, 11); michael@0: michael@0: // set bookmark title michael@0: bs.setItemTitle(newId13, "ZZZXXXYYY"); michael@0: do_check_eq(bookmarksObserver._itemChangedId, newId13); michael@0: do_check_eq(bookmarksObserver._itemChangedProperty, "title"); michael@0: do_check_eq(bookmarksObserver._itemChangedValue, "ZZZXXXYYY"); michael@0: michael@0: // check if setting an item annotation triggers onItemChanged michael@0: bookmarksObserver._itemChangedId = -1; michael@0: anno.setItemAnnotation(newId3, "test-annotation", "foo", 0, 0); michael@0: do_check_eq(bookmarksObserver._itemChangedId, newId3); michael@0: do_check_eq(bookmarksObserver._itemChangedProperty, "test-annotation"); michael@0: do_check_true(bookmarksObserver._itemChanged_isAnnotationProperty); michael@0: do_check_eq(bookmarksObserver._itemChangedValue, ""); michael@0: michael@0: // test search on bookmark title ZZZXXXYYY michael@0: try { michael@0: let options = hs.getNewQueryOptions(); michael@0: options.excludeQueries = 1; michael@0: options.queryType = Ci.nsINavHistoryQueryOptions.QUERY_TYPE_BOOKMARKS; michael@0: let query = hs.getNewQuery(); michael@0: query.searchTerms = "ZZZXXXYYY"; michael@0: let result = hs.executeQuery(query, options); michael@0: let rootNode = result.root; michael@0: rootNode.containerOpen = true; michael@0: let cc = rootNode.childCount; michael@0: do_check_eq(cc, 1); michael@0: let node = rootNode.getChild(0); michael@0: do_check_eq(node.title, "ZZZXXXYYY"); michael@0: do_check_true(node.itemId > 0); michael@0: rootNode.containerOpen = false; michael@0: } michael@0: catch(ex) { michael@0: do_throw("bookmarks query: " + ex); michael@0: } michael@0: michael@0: // test dateAdded and lastModified properties michael@0: // for a search query michael@0: try { michael@0: let options = hs.getNewQueryOptions(); michael@0: options.excludeQueries = 1; michael@0: options.queryType = Ci.nsINavHistoryQueryOptions.QUERY_TYPE_BOOKMARKS; michael@0: let query = hs.getNewQuery(); michael@0: query.searchTerms = "ZZZXXXYYY"; michael@0: let result = hs.executeQuery(query, options); michael@0: let rootNode = result.root; michael@0: rootNode.containerOpen = true; michael@0: let cc = rootNode.childCount; michael@0: do_check_eq(cc, 1); michael@0: let node = rootNode.getChild(0); michael@0: michael@0: do_check_eq(typeof node.dateAdded, "number"); michael@0: do_check_true(node.dateAdded > 0); michael@0: michael@0: do_check_eq(typeof node.lastModified, "number"); michael@0: do_check_true(node.lastModified > 0); michael@0: michael@0: rootNode.containerOpen = false; michael@0: } michael@0: catch(ex) { michael@0: do_throw("bookmarks query: " + ex); michael@0: } michael@0: michael@0: // test dateAdded and lastModified properties michael@0: // for a folder query michael@0: try { michael@0: let options = hs.getNewQueryOptions(); michael@0: let query = hs.getNewQuery(); michael@0: query.setFolders([testRoot], 1); michael@0: let result = hs.executeQuery(query, options); michael@0: let rootNode = result.root; michael@0: rootNode.containerOpen = true; michael@0: let cc = rootNode.childCount; michael@0: do_check_true(cc > 0); michael@0: for (let i = 0; i < cc; i++) { michael@0: let node = rootNode.getChild(i); michael@0: michael@0: if (node.type == node.RESULT_TYPE_URI) { michael@0: do_check_eq(typeof node.dateAdded, "number"); michael@0: do_check_true(node.dateAdded > 0); michael@0: michael@0: do_check_eq(typeof node.lastModified, "number"); michael@0: do_check_true(node.lastModified > 0); michael@0: break; michael@0: } michael@0: } michael@0: rootNode.containerOpen = false; michael@0: } michael@0: catch(ex) { michael@0: do_throw("bookmarks query: " + ex); michael@0: } michael@0: michael@0: // check setItemLastModified() and setItemDateAdded() michael@0: let newId14 = bs.insertBookmark(testRoot, uri("http://bar.tld/"), michael@0: bs.DEFAULT_INDEX, ""); michael@0: let dateAdded = bs.getItemDateAdded(newId14); michael@0: let lastModified = bs.getItemLastModified(newId14); michael@0: do_check_eq(lastModified, dateAdded); michael@0: bs.setItemLastModified(newId14, 1234); michael@0: let fakeLastModified = bs.getItemLastModified(newId14); michael@0: do_check_eq(fakeLastModified, 1234); michael@0: bs.setItemDateAdded(newId14, 4321); michael@0: let fakeDateAdded = bs.getItemDateAdded(newId14); michael@0: do_check_eq(fakeDateAdded, 4321); michael@0: michael@0: // ensure that removing an item removes its annotations michael@0: do_check_true(anno.itemHasAnnotation(newId3, "test-annotation")); michael@0: bs.removeItem(newId3); michael@0: do_check_false(anno.itemHasAnnotation(newId3, "test-annotation")); michael@0: michael@0: // bug 378820 michael@0: let uri1 = uri("http://foo.tld/a"); michael@0: bs.insertBookmark(testRoot, uri1, bs.DEFAULT_INDEX, ""); michael@0: yield promiseAddVisits(uri1); michael@0: michael@0: // bug 646993 - test bookmark titles longer than the maximum allowed length michael@0: let title15 = Array(TITLE_LENGTH_MAX + 5).join("X"); michael@0: let title15expected = title15.substring(0, TITLE_LENGTH_MAX); michael@0: let newId15 = bs.insertBookmark(testRoot, uri("http://evil.com/"), michael@0: bs.DEFAULT_INDEX, title15); michael@0: michael@0: do_check_eq(bs.getItemTitle(newId15).length, michael@0: title15expected.length); michael@0: do_check_eq(bookmarksObserver._itemAddedTitle, title15expected); michael@0: // test title length after updates michael@0: bs.setItemTitle(newId15, title15 + " updated"); michael@0: do_check_eq(bs.getItemTitle(newId15).length, michael@0: title15expected.length); michael@0: do_check_eq(bookmarksObserver._itemChangedId, newId15); michael@0: do_check_eq(bookmarksObserver._itemChangedProperty, "title"); michael@0: do_check_eq(bookmarksObserver._itemChangedValue, title15expected); michael@0: michael@0: testSimpleFolderResult(); michael@0: }); michael@0: michael@0: function testSimpleFolderResult() { michael@0: // the time before we create a folder, in microseconds michael@0: // Workaround possible VM timers issues subtracting 1us. michael@0: let beforeCreate = Date.now() * 1000 - 1; michael@0: do_check_true(beforeCreate > 0); michael@0: michael@0: // create a folder michael@0: let parent = bs.createFolder(root, "test", bs.DEFAULT_INDEX); michael@0: michael@0: let dateCreated = bs.getItemDateAdded(parent); michael@0: LOG("check that the folder was created with a valid dateAdded"); michael@0: LOG("beforeCreate = " + beforeCreate); michael@0: LOG("dateCreated = " + dateCreated); michael@0: do_check_true(is_time_ordered(beforeCreate, dateCreated)); michael@0: michael@0: // the time before we insert, in microseconds michael@0: // Workaround possible VM timers issues subtracting 1ms. michael@0: let beforeInsert = Date.now() * 1000 - 1; michael@0: do_check_true(beforeInsert > 0); michael@0: michael@0: // insert a separator michael@0: let sep = bs.insertSeparator(parent, bs.DEFAULT_INDEX); michael@0: michael@0: let dateAdded = bs.getItemDateAdded(sep); michael@0: LOG("check that the separator was created with a valid dateAdded"); michael@0: LOG("beforeInsert = " + beforeInsert); michael@0: LOG("dateAdded = " + dateAdded); michael@0: do_check_true(is_time_ordered(beforeInsert, dateAdded)); michael@0: michael@0: // re-set item title separately so can test nodes' last modified michael@0: let item = bs.insertBookmark(parent, uri("about:blank"), michael@0: bs.DEFAULT_INDEX, ""); michael@0: bs.setItemTitle(item, "test bookmark"); michael@0: michael@0: // see above michael@0: let folder = bs.createFolder(parent, "test folder", bs.DEFAULT_INDEX); michael@0: bs.setItemTitle(folder, "test folder"); michael@0: michael@0: let longName = Array(TITLE_LENGTH_MAX + 5).join("A"); michael@0: let folderLongName = bs.createFolder(parent, longName, bs.DEFAULT_INDEX); michael@0: do_check_eq(bookmarksObserver._itemAddedTitle, longName.substring(0, TITLE_LENGTH_MAX)); michael@0: michael@0: let options = hs.getNewQueryOptions(); michael@0: let query = hs.getNewQuery(); michael@0: query.setFolders([parent], 1); michael@0: let result = hs.executeQuery(query, options); michael@0: let rootNode = result.root; michael@0: rootNode.containerOpen = true; michael@0: do_check_eq(rootNode.childCount, 4); michael@0: michael@0: let node = rootNode.getChild(0); michael@0: do_check_true(node.dateAdded > 0); michael@0: do_check_eq(node.lastModified, node.dateAdded); michael@0: do_check_eq(node.itemId, sep); michael@0: do_check_eq(node.title, ""); michael@0: node = rootNode.getChild(1); michael@0: do_check_eq(node.itemId, item); michael@0: do_check_true(node.dateAdded > 0); michael@0: do_check_true(node.lastModified > 0); michael@0: do_check_eq(node.title, "test bookmark"); michael@0: node = rootNode.getChild(2); michael@0: do_check_eq(node.itemId, folder); michael@0: do_check_eq(node.title, "test folder"); michael@0: do_check_true(node.dateAdded > 0); michael@0: do_check_true(node.lastModified > 0); michael@0: node = rootNode.getChild(3); michael@0: do_check_eq(node.itemId, folderLongName); michael@0: do_check_eq(node.title, longName.substring(0, TITLE_LENGTH_MAX)); michael@0: do_check_true(node.dateAdded > 0); michael@0: do_check_true(node.lastModified > 0); michael@0: michael@0: // update with another long title michael@0: bs.setItemTitle(folderLongName, longName + " updated"); michael@0: do_check_eq(bookmarksObserver._itemChangedId, folderLongName); michael@0: do_check_eq(bookmarksObserver._itemChangedProperty, "title"); michael@0: do_check_eq(bookmarksObserver._itemChangedValue, longName.substring(0, TITLE_LENGTH_MAX)); michael@0: michael@0: node = rootNode.getChild(3); michael@0: do_check_eq(node.title, longName.substring(0, TITLE_LENGTH_MAX)); michael@0: michael@0: rootNode.containerOpen = false; michael@0: } michael@0: michael@0: function getChildCount(aFolderId) { michael@0: let cc = -1; michael@0: try { michael@0: let options = hs.getNewQueryOptions(); michael@0: let query = hs.getNewQuery(); michael@0: query.setFolders([aFolderId], 1); michael@0: let result = hs.executeQuery(query, options); michael@0: let rootNode = result.root; michael@0: rootNode.containerOpen = true; michael@0: cc = rootNode.childCount; michael@0: rootNode.containerOpen = false; michael@0: } catch(ex) { michael@0: do_throw("getChildCount failed: " + ex); michael@0: } michael@0: return cc; michael@0: }