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: const LOAD_IN_SIDEBAR_ANNO = "bookmarkProperties/loadInSidebar"; michael@0: const DESCRIPTION_ANNO = "bookmarkProperties/description"; michael@0: const POST_DATA_ANNO = "bookmarkProperties/POSTData"; michael@0: michael@0: do_check_eq(typeof PlacesUtils, "object"); michael@0: michael@0: // main michael@0: function run_test() { michael@0: do_test_pending(); michael@0: michael@0: /* michael@0: HTML+FEATURES SUMMARY: michael@0: - import legacy bookmarks michael@0: - export as json, import, test (tests integrity of html > json) michael@0: - export as html, import, test (tests integrity of json > html) michael@0: michael@0: BACKUP/RESTORE SUMMARY: michael@0: - create a bookmark in each root michael@0: - tag multiple URIs with multiple tags michael@0: - export as json, import, test michael@0: */ michael@0: michael@0: // import the importer michael@0: Cu.import("resource://gre/modules/BookmarkHTMLUtils.jsm"); michael@0: michael@0: // file pointer to legacy bookmarks file michael@0: var bookmarksFileOld = OS.Path.join(do_get_cwd().path, "bookmarks.preplaces.html"); michael@0: // file pointer to a new places-exported json file michael@0: var jsonFile = OS.Path.join(OS.Constants.Path.profileDir, "bookmarks.exported.json"); michael@0: Task.spawn(function () { michael@0: // create bookmarks.exported.json michael@0: if ((yield OS.File.exists(jsonFile))) michael@0: yield OS.File.remove(jsonFile); michael@0: michael@0: // Test importing a pre-Places canonical bookmarks file. michael@0: // 1. import bookmarks.preplaces.html michael@0: // Note: we do not empty the db before this import to catch bugs like 380999 michael@0: try { michael@0: BookmarkHTMLUtils.importFromFile(bookmarksFileOld, true) michael@0: .then(after_import, do_report_unexpected_exception); michael@0: } catch(ex) { do_throw("couldn't import legacy bookmarks file: " + ex); } michael@0: }); michael@0: michael@0: function after_import() { michael@0: populate(); michael@0: michael@0: // 2. run the test-suite michael@0: Task.spawn(function() { michael@0: yield validate(); michael@0: yield promiseAsyncUpdates(); michael@0: michael@0: // Test exporting a Places canonical json file. michael@0: // 1. export to bookmarks.exported.json michael@0: try { michael@0: yield BookmarkJSONUtils.exportToFile(jsonFile); michael@0: } catch(ex) { do_throw("couldn't export to file: " + ex); } michael@0: LOG("exported json"); michael@0: michael@0: // 2. empty bookmarks db michael@0: // 3. import bookmarks.exported.json michael@0: try { michael@0: yield BookmarkJSONUtils.importFromFile(jsonFile, true); michael@0: } catch(ex) { do_throw("couldn't import the exported file: " + ex); } michael@0: LOG("imported json"); michael@0: michael@0: // 4. run the test-suite michael@0: yield validate(); michael@0: LOG("validated import"); michael@0: michael@0: yield promiseAsyncUpdates(); michael@0: do_test_finished(); michael@0: }); michael@0: } michael@0: } michael@0: michael@0: var tagData = [ michael@0: { uri: uri("http://slint.us"), tags: ["indie", "kentucky", "music"] }, michael@0: { uri: uri("http://en.wikipedia.org/wiki/Diplodocus"), tags: ["dinosaur", "dj", "rad word"] } michael@0: ]; michael@0: michael@0: var bookmarkData = [ michael@0: { uri: uri("http://slint.us"), title: "indie, kentucky, music" }, michael@0: { uri: uri("http://en.wikipedia.org/wiki/Diplodocus"), title: "dinosaur, dj, rad word" } michael@0: ]; michael@0: michael@0: /* michael@0: populate data in each folder michael@0: (menu is populated via the html import) michael@0: */ michael@0: function populate() { michael@0: // add tags michael@0: for each(let {uri: u, tags: t} in tagData) michael@0: PlacesUtils.tagging.tagURI(u, t); michael@0: michael@0: // add unfiled bookmarks michael@0: for each(let {uri: u, title: t} in bookmarkData) { michael@0: PlacesUtils.bookmarks.insertBookmark(PlacesUtils.bookmarks.unfiledBookmarksFolder, michael@0: u, PlacesUtils.bookmarks.DEFAULT_INDEX, t); michael@0: } michael@0: michael@0: // add to the toolbar michael@0: for each(let {uri: u, title: t} in bookmarkData) { michael@0: PlacesUtils.bookmarks.insertBookmark(PlacesUtils.bookmarks.toolbarFolder, michael@0: u, PlacesUtils.bookmarks.DEFAULT_INDEX, t); michael@0: } michael@0: } michael@0: michael@0: function validate() { michael@0: yield testCanonicalBookmarks(); michael@0: yield testToolbarFolder(); michael@0: testUnfiledBookmarks(); michael@0: testTags(); michael@0: } michael@0: michael@0: // Tests a bookmarks datastore that has a set of bookmarks, etc michael@0: // that flex each supported field and feature. michael@0: function testCanonicalBookmarks() { michael@0: // query to see if the deleted folder and items have been imported michael@0: var query = PlacesUtils.history.getNewQuery(); michael@0: query.setFolders([PlacesUtils.bookmarksMenuFolderId], 1); michael@0: var result = PlacesUtils.history.executeQuery(query, PlacesUtils.history.getNewQueryOptions()); michael@0: var rootNode = result.root; michael@0: rootNode.containerOpen = true; michael@0: michael@0: // Count expected bookmarks in the menu root. michael@0: do_check_eq(rootNode.childCount, 3); michael@0: michael@0: // check separator michael@0: var testSeparator = rootNode.getChild(1); michael@0: do_check_eq(testSeparator.type, testSeparator.RESULT_TYPE_SEPARATOR); michael@0: michael@0: // get test folder michael@0: var testFolder = rootNode.getChild(2); michael@0: do_check_eq(testFolder.type, testFolder.RESULT_TYPE_FOLDER); michael@0: do_check_eq(testFolder.title, "test"); michael@0: michael@0: /* michael@0: // add date michael@0: do_check_eq(PlacesUtils.bookmarks.getItemDateAdded(testFolder.itemId)/1000000, 1177541020); michael@0: // last modified michael@0: do_check_eq(PlacesUtils.bookmarks.getItemLastModified(testFolder.itemId)/1000000, 1177541050); michael@0: */ michael@0: michael@0: testFolder = testFolder.QueryInterface(Ci.nsINavHistoryQueryResultNode); michael@0: do_check_eq(testFolder.hasChildren, true); michael@0: // folder description michael@0: do_check_true(PlacesUtils.annotations.itemHasAnnotation(testFolder.itemId, michael@0: DESCRIPTION_ANNO)); michael@0: do_check_eq("folder test comment", michael@0: PlacesUtils.annotations.getItemAnnotation(testFolder.itemId, DESCRIPTION_ANNO)); michael@0: // open test folder, and test the children michael@0: testFolder.containerOpen = true; michael@0: var cc = testFolder.childCount; michael@0: // XXX Bug 380468 michael@0: // do_check_eq(cc, 2); michael@0: do_check_eq(cc, 1); michael@0: michael@0: // test bookmark 1 michael@0: var testBookmark1 = testFolder.getChild(0); michael@0: // url michael@0: do_check_eq("http://test/post", testBookmark1.uri); michael@0: // title michael@0: do_check_eq("test post keyword", testBookmark1.title); michael@0: // keyword michael@0: do_check_eq("test", PlacesUtils.bookmarks.getKeywordForBookmark(testBookmark1.itemId)); michael@0: // sidebar michael@0: do_check_true(PlacesUtils.annotations.itemHasAnnotation(testBookmark1.itemId, michael@0: LOAD_IN_SIDEBAR_ANNO)); michael@0: /* michael@0: // add date michael@0: do_check_eq(testBookmark1.dateAdded/1000000, 1177375336); michael@0: michael@0: // last modified michael@0: do_check_eq(testBookmark1.lastModified/1000000, 1177375423); michael@0: */ michael@0: michael@0: // post data michael@0: do_check_true(PlacesUtils.annotations.itemHasAnnotation(testBookmark1.itemId, POST_DATA_ANNO)); michael@0: do_check_eq("hidden1%3Dbar&text1%3D%25s", michael@0: PlacesUtils.annotations.getItemAnnotation(testBookmark1.itemId, POST_DATA_ANNO)); michael@0: michael@0: // last charset michael@0: var testURI = PlacesUtils._uri(testBookmark1.uri); michael@0: do_check_eq("ISO-8859-1", (yield PlacesUtils.getCharsetForURI(testURI))); michael@0: michael@0: // description michael@0: do_check_true(PlacesUtils.annotations.itemHasAnnotation(testBookmark1.itemId, michael@0: DESCRIPTION_ANNO)); michael@0: do_check_eq("item description", michael@0: PlacesUtils.annotations.getItemAnnotation(testBookmark1.itemId, michael@0: DESCRIPTION_ANNO)); michael@0: michael@0: // clean up michael@0: testFolder.containerOpen = false; michael@0: rootNode.containerOpen = false; michael@0: } michael@0: michael@0: function testToolbarFolder() { michael@0: var query = PlacesUtils.history.getNewQuery(); michael@0: query.setFolders([PlacesUtils.toolbarFolderId], 1); michael@0: var result = PlacesUtils.history.executeQuery(query, PlacesUtils.history.getNewQueryOptions()); michael@0: michael@0: var toolbar = result.root; michael@0: toolbar.containerOpen = true; michael@0: michael@0: // child count (add 2 for pre-existing items) michael@0: do_check_eq(toolbar.childCount, bookmarkData.length + 2); michael@0: michael@0: // livemark michael@0: var livemark = toolbar.getChild(1); michael@0: // title michael@0: do_check_eq("Latest Headlines", livemark.title); michael@0: michael@0: let foundLivemark = yield PlacesUtils.livemarks.getLivemark({ id: livemark.itemId }); michael@0: do_check_eq("http://en-us.fxfeeds.mozilla.com/en-US/firefox/livebookmarks/", michael@0: foundLivemark.siteURI.spec); michael@0: do_check_eq("http://en-us.fxfeeds.mozilla.com/en-US/firefox/headlines.xml", michael@0: foundLivemark.feedURI.spec); michael@0: michael@0: // test added bookmark data michael@0: var child = toolbar.getChild(2); michael@0: do_check_eq(child.uri, bookmarkData[0].uri.spec); michael@0: do_check_eq(child.title, bookmarkData[0].title); michael@0: child = toolbar.getChild(3); michael@0: do_check_eq(child.uri, bookmarkData[1].uri.spec); michael@0: do_check_eq(child.title, bookmarkData[1].title); michael@0: michael@0: toolbar.containerOpen = false; michael@0: } michael@0: michael@0: function testUnfiledBookmarks() { michael@0: var query = PlacesUtils.history.getNewQuery(); michael@0: query.setFolders([PlacesUtils.unfiledBookmarksFolderId], 1); michael@0: var result = PlacesUtils.history.executeQuery(query, PlacesUtils.history.getNewQueryOptions()); michael@0: var rootNode = result.root; michael@0: rootNode.containerOpen = true; michael@0: // child count (add 1 for pre-existing item) michael@0: do_check_eq(rootNode.childCount, bookmarkData.length + 1); michael@0: for (var i = 1; i < rootNode.childCount; i++) { michael@0: var child = rootNode.getChild(i); michael@0: dump(bookmarkData[i - 1].uri.spec + " == " + child.uri + "?\n"); michael@0: do_check_true(bookmarkData[i - 1].uri.equals(uri(child.uri))); michael@0: do_check_eq(child.title, bookmarkData[i - 1].title); michael@0: /* WTF michael@0: if (child.tags) michael@0: do_check_eq(child.tags, bookmarkData[i].title); michael@0: */ michael@0: } michael@0: rootNode.containerOpen = false; michael@0: } michael@0: michael@0: function testTags() { michael@0: for each(let {uri: u, tags: t} in tagData) { michael@0: var i = 0; michael@0: dump("test tags for " + u.spec + ": " + t + "\n"); michael@0: var tt = PlacesUtils.tagging.getTagsForURI(u); michael@0: dump("true tags for " + u.spec + ": " + tt + "\n"); michael@0: do_check_true(t.every(function(el) { michael@0: i++; michael@0: return tt.indexOf(el) > -1; michael@0: })); michael@0: do_check_eq(i, t.length); michael@0: } michael@0: }