mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-10-22 15:17:29 +09:00
import FIREFOX_52_6_0esr_RELEASE from mozilla-esr52 hg repo
This commit is contained in:
commit
dcd9973243
150858 changed files with 23884658 additions and 0 deletions
7
toolkit/components/places/tests/bookmarks/.eslintrc.js
Normal file
7
toolkit/components/places/tests/bookmarks/.eslintrc.js
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
"use strict";
|
||||
|
||||
module.exports = {
|
||||
"extends": [
|
||||
"../../../../../testing/xpcshell/xpcshell.eslintrc.js"
|
||||
]
|
||||
};
|
||||
20
toolkit/components/places/tests/bookmarks/head_bookmarks.js
Normal file
20
toolkit/components/places/tests/bookmarks/head_bookmarks.js
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
var Ci = Components.interfaces;
|
||||
var Cc = Components.classes;
|
||||
var Cr = Components.results;
|
||||
var Cu = Components.utils;
|
||||
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
|
||||
// Import common head.
|
||||
{
|
||||
let commonFile = do_get_file("../head_common.js", false);
|
||||
let uri = Services.io.newFileURI(commonFile);
|
||||
Services.scriptloader.loadSubScript(uri.spec, this);
|
||||
}
|
||||
|
||||
// Put any other stuff relative to this test folder below.
|
||||
|
|
@ -0,0 +1,103 @@
|
|||
function run_test() {
|
||||
run_next_test();
|
||||
}
|
||||
|
||||
/* Bug 1016953 - When a previous bookmark backup exists with the same hash
|
||||
regardless of date, an automatic backup should attempt to either rename it to
|
||||
today's date if the backup was for an old date or leave it alone if it was for
|
||||
the same date. However if the file ext was json it will accidentally rename it
|
||||
to jsonlz4 while keeping the json contents
|
||||
*/
|
||||
|
||||
add_task(function* test_same_date_same_hash() {
|
||||
// If old file has been created on the same date and has the same hash
|
||||
// the file should be left alone
|
||||
let backupFolder = yield PlacesBackups.getBackupFolder();
|
||||
// Save to profile dir to obtain hash and nodeCount to append to filename
|
||||
let tempPath = OS.Path.join(OS.Constants.Path.profileDir,
|
||||
"bug10169583_bookmarks.json");
|
||||
let {count, hash} = yield BookmarkJSONUtils.exportToFile(tempPath);
|
||||
|
||||
// Save JSON file in backup folder with hash appended
|
||||
let dateObj = new Date();
|
||||
let filename = "bookmarks-" + PlacesBackups.toISODateString(dateObj) + "_" +
|
||||
count + "_" + hash + ".json";
|
||||
let backupFile = OS.Path.join(backupFolder, filename);
|
||||
yield OS.File.move(tempPath, backupFile);
|
||||
|
||||
// Force a compressed backup which fallbacks to rename
|
||||
yield PlacesBackups.create();
|
||||
let mostRecentBackupFile = yield PlacesBackups.getMostRecentBackup();
|
||||
// check to ensure not renamed to jsonlz4
|
||||
Assert.equal(mostRecentBackupFile, backupFile);
|
||||
// inspect contents and check if valid json
|
||||
let converter = Cc["@mozilla.org/intl/scriptableunicodeconverter"].
|
||||
createInstance(Ci.nsIScriptableUnicodeConverter);
|
||||
converter.charset = "UTF-8";
|
||||
let result = yield OS.File.read(mostRecentBackupFile);
|
||||
let jsonString = converter.convertFromByteArray(result, result.length);
|
||||
do_print("Check is valid JSON");
|
||||
JSON.parse(jsonString);
|
||||
|
||||
// Cleanup
|
||||
yield OS.File.remove(backupFile);
|
||||
yield OS.File.remove(tempPath);
|
||||
PlacesBackups._backupFiles = null; // To force re-cache of backupFiles
|
||||
});
|
||||
|
||||
add_task(function* test_same_date_diff_hash() {
|
||||
// If the old file has been created on the same date, but has a different hash
|
||||
// the existing file should be overwritten with the newer compressed version
|
||||
let backupFolder = yield PlacesBackups.getBackupFolder();
|
||||
let tempPath = OS.Path.join(OS.Constants.Path.profileDir,
|
||||
"bug10169583_bookmarks.json");
|
||||
let {count} = yield BookmarkJSONUtils.exportToFile(tempPath);
|
||||
let dateObj = new Date();
|
||||
let filename = "bookmarks-" + PlacesBackups.toISODateString(dateObj) + "_" +
|
||||
count + "_" + "differentHash==" + ".json";
|
||||
let backupFile = OS.Path.join(backupFolder, filename);
|
||||
yield OS.File.move(tempPath, backupFile);
|
||||
yield PlacesBackups.create(); // Force compressed backup
|
||||
mostRecentBackupFile = yield PlacesBackups.getMostRecentBackup();
|
||||
|
||||
// Decode lz4 compressed file to json and check if json is valid
|
||||
let converter = Cc["@mozilla.org/intl/scriptableunicodeconverter"].
|
||||
createInstance(Ci.nsIScriptableUnicodeConverter);
|
||||
converter.charset = "UTF-8";
|
||||
let result = yield OS.File.read(mostRecentBackupFile, { compression: "lz4" });
|
||||
let jsonString = converter.convertFromByteArray(result, result.length);
|
||||
do_print("Check is valid JSON");
|
||||
JSON.parse(jsonString);
|
||||
|
||||
// Cleanup
|
||||
yield OS.File.remove(mostRecentBackupFile);
|
||||
yield OS.File.remove(tempPath);
|
||||
PlacesBackups._backupFiles = null; // To force re-cache of backupFiles
|
||||
});
|
||||
|
||||
add_task(function* test_diff_date_same_hash() {
|
||||
// If the old file has been created on an older day but has the same hash
|
||||
// it should be renamed with today's date without altering the contents.
|
||||
let backupFolder = yield PlacesBackups.getBackupFolder();
|
||||
let tempPath = OS.Path.join(OS.Constants.Path.profileDir,
|
||||
"bug10169583_bookmarks.json");
|
||||
let {count, hash} = yield BookmarkJSONUtils.exportToFile(tempPath);
|
||||
let oldDate = new Date(2014, 1, 1);
|
||||
let curDate = new Date();
|
||||
let oldFilename = "bookmarks-" + PlacesBackups.toISODateString(oldDate) + "_" +
|
||||
count + "_" + hash + ".json";
|
||||
let newFilename = "bookmarks-" + PlacesBackups.toISODateString(curDate) + "_" +
|
||||
count + "_" + hash + ".json";
|
||||
let backupFile = OS.Path.join(backupFolder, oldFilename);
|
||||
let newBackupFile = OS.Path.join(backupFolder, newFilename);
|
||||
yield OS.File.move(tempPath, backupFile);
|
||||
|
||||
// Ensure file has been renamed correctly
|
||||
yield PlacesBackups.create();
|
||||
let mostRecentBackupFile = yield PlacesBackups.getMostRecentBackup();
|
||||
Assert.equal(mostRecentBackupFile, newBackupFile);
|
||||
|
||||
// Cleanup
|
||||
yield OS.File.remove(mostRecentBackupFile);
|
||||
yield OS.File.remove(tempPath);
|
||||
});
|
||||
|
|
@ -0,0 +1,112 @@
|
|||
/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim:set ts=2 sw=2 sts=2 et: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/* Bug 1017502 - Add a foreign_count column to moz_places
|
||||
This tests, tests the triggers that adjust the foreign_count when a bookmark is
|
||||
added or removed and also the maintenance task to fix wrong counts.
|
||||
*/
|
||||
|
||||
const T_URI = NetUtil.newURI("https://www.mozilla.org/firefox/nightly/firstrun/");
|
||||
|
||||
function* getForeignCountForURL(conn, url) {
|
||||
yield PlacesTestUtils.promiseAsyncUpdates();
|
||||
url = url instanceof Ci.nsIURI ? url.spec : url;
|
||||
let rows = yield conn.executeCached(
|
||||
`SELECT foreign_count FROM moz_places WHERE url_hash = hash(:t_url)
|
||||
AND url = :t_url`, { t_url: url });
|
||||
return rows[0].getResultByName("foreign_count");
|
||||
}
|
||||
|
||||
function run_test() {
|
||||
run_next_test();
|
||||
}
|
||||
|
||||
add_task(function* add_remove_change_bookmark_test() {
|
||||
let conn = yield PlacesUtils.promiseDBConnection();
|
||||
|
||||
// Simulate a visit to the url
|
||||
yield PlacesTestUtils.addVisits(T_URI);
|
||||
Assert.equal((yield getForeignCountForURL(conn, T_URI)), 0);
|
||||
|
||||
// Add 1st bookmark which should increment foreign_count by 1
|
||||
let id1 = PlacesUtils.bookmarks.insertBookmark(PlacesUtils.unfiledBookmarksFolderId,
|
||||
T_URI, PlacesUtils.bookmarks.DEFAULT_INDEX, "First Run");
|
||||
Assert.equal((yield getForeignCountForURL(conn, T_URI)), 1);
|
||||
|
||||
// Add 2nd bookmark
|
||||
let id2 = PlacesUtils.bookmarks.insertBookmark(PlacesUtils.bookmarksMenuFolderId,
|
||||
T_URI, PlacesUtils.bookmarks.DEFAULT_INDEX, "First Run");
|
||||
Assert.equal((yield getForeignCountForURL(conn, T_URI)), 2);
|
||||
|
||||
// Remove 2nd bookmark which should decrement foreign_count by 1
|
||||
PlacesUtils.bookmarks.removeItem(id2);
|
||||
Assert.equal((yield getForeignCountForURL(conn, T_URI)), 1);
|
||||
|
||||
// Change first bookmark's URI
|
||||
const URI2 = NetUtil.newURI("http://www.mozilla.org");
|
||||
PlacesUtils.bookmarks.changeBookmarkURI(id1, URI2);
|
||||
// Check foreign count for original URI
|
||||
Assert.equal((yield getForeignCountForURL(conn, T_URI)), 0);
|
||||
// Check foreign count for new URI
|
||||
Assert.equal((yield getForeignCountForURL(conn, URI2)), 1);
|
||||
|
||||
// Cleanup - Remove changed bookmark
|
||||
let id = PlacesUtils.bookmarks.getBookmarkIdsForURI(URI2);
|
||||
PlacesUtils.bookmarks.removeItem(id);
|
||||
Assert.equal((yield getForeignCountForURL(conn, URI2)), 0);
|
||||
|
||||
});
|
||||
|
||||
add_task(function* maintenance_foreign_count_test() {
|
||||
let conn = yield PlacesUtils.promiseDBConnection();
|
||||
|
||||
// Simulate a visit to the url
|
||||
yield PlacesTestUtils.addVisits(T_URI);
|
||||
|
||||
// Adjust the foreign_count for the added entry to an incorrect value
|
||||
let deferred = Promise.defer();
|
||||
let stmt = DBConn().createAsyncStatement(
|
||||
`UPDATE moz_places SET foreign_count = 10 WHERE url_hash = hash(:t_url)
|
||||
AND url = :t_url `);
|
||||
stmt.params.t_url = T_URI.spec;
|
||||
stmt.executeAsync({
|
||||
handleCompletion: function() {
|
||||
deferred.resolve();
|
||||
}
|
||||
});
|
||||
stmt.finalize();
|
||||
yield deferred.promise;
|
||||
Assert.equal((yield getForeignCountForURL(conn, T_URI)), 10);
|
||||
|
||||
// Run maintenance
|
||||
Components.utils.import("resource://gre/modules/PlacesDBUtils.jsm");
|
||||
let promiseMaintenanceFinished =
|
||||
promiseTopicObserved("places-maintenance-finished");
|
||||
PlacesDBUtils.maintenanceOnIdle();
|
||||
yield promiseMaintenanceFinished;
|
||||
|
||||
// Check if the foreign_count has been adjusted to the correct value
|
||||
Assert.equal((yield getForeignCountForURL(conn, T_URI)), 0);
|
||||
});
|
||||
|
||||
add_task(function* add_remove_tags_test() {
|
||||
let conn = yield PlacesUtils.promiseDBConnection();
|
||||
|
||||
yield PlacesTestUtils.addVisits(T_URI);
|
||||
Assert.equal((yield getForeignCountForURL(conn, T_URI)), 0);
|
||||
|
||||
// Check foreign count incremented by 1 for a single tag
|
||||
PlacesUtils.tagging.tagURI(T_URI, ["test tag"]);
|
||||
Assert.equal((yield getForeignCountForURL(conn, T_URI)), 1);
|
||||
|
||||
// Check foreign count is incremented by 2 for two tags
|
||||
PlacesUtils.tagging.tagURI(T_URI, ["one", "two"]);
|
||||
Assert.equal((yield getForeignCountForURL(conn, T_URI)), 3);
|
||||
|
||||
// Check foreign count is set to 0 when all tags are removed
|
||||
PlacesUtils.tagging.untagURI(T_URI, ["test tag", "one", "two"]);
|
||||
Assert.equal((yield getForeignCountForURL(conn, T_URI)), 0);
|
||||
});
|
||||
76
toolkit/components/places/tests/bookmarks/test_1129529.js
Normal file
76
toolkit/components/places/tests/bookmarks/test_1129529.js
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
var now = Date.now() * 1000;
|
||||
|
||||
// Test that importing bookmark data where a bookmark has a tag longer than 100
|
||||
// chars imports everything except the tags for that bookmark.
|
||||
add_task(function* () {
|
||||
let aData = {
|
||||
guid: "root________",
|
||||
index: 0,
|
||||
id: 1,
|
||||
type: "text/x-moz-place-container",
|
||||
dateAdded: now,
|
||||
lastModified: now,
|
||||
root: "placesRoot",
|
||||
children: [{
|
||||
guid: "unfiled_____",
|
||||
index: 0,
|
||||
id: 2,
|
||||
type: "text/x-moz-place-container",
|
||||
dateAdded: now,
|
||||
lastModified: now,
|
||||
root: "unfiledBookmarksFolder",
|
||||
children: [
|
||||
{
|
||||
guid: "___guid1____",
|
||||
index: 0,
|
||||
id: 3,
|
||||
charset: "UTF-8",
|
||||
tags: "tag0",
|
||||
type: "text/x-moz-place",
|
||||
dateAdded: now,
|
||||
lastModified: now,
|
||||
uri: "http://test0.com/"
|
||||
},
|
||||
{
|
||||
guid: "___guid2____",
|
||||
index: 1,
|
||||
id: 4,
|
||||
charset: "UTF-8",
|
||||
tags: "tag1," + "a" + "0123456789".repeat(10), // 101 chars
|
||||
type: "text/x-moz-place",
|
||||
dateAdded: now,
|
||||
lastModified: now,
|
||||
uri: "http://test1.com/"
|
||||
},
|
||||
{
|
||||
guid: "___guid3____",
|
||||
index: 2,
|
||||
id: 5,
|
||||
charset: "UTF-8",
|
||||
tags: "tag2",
|
||||
type: "text/x-moz-place",
|
||||
dateAdded: now,
|
||||
lastModified: now,
|
||||
uri: "http://test2.com/"
|
||||
}
|
||||
]
|
||||
}]
|
||||
};
|
||||
|
||||
let contentType = "application/json";
|
||||
let uri = "data:" + contentType + "," + JSON.stringify(aData);
|
||||
yield BookmarkJSONUtils.importFromURL(uri, false);
|
||||
|
||||
let [bookmarks] = yield PlacesBackups.getBookmarksTree();
|
||||
let unsortedBookmarks = bookmarks.children[2].children;
|
||||
Assert.equal(unsortedBookmarks.length, 3);
|
||||
|
||||
for (let i = 0; i < unsortedBookmarks.length; ++i) {
|
||||
let bookmark = unsortedBookmarks[i];
|
||||
Assert.equal(bookmark.charset, "UTF-8");
|
||||
Assert.equal(bookmark.dateAdded, now);
|
||||
Assert.equal(bookmark.lastModified, now);
|
||||
Assert.equal(bookmark.uri, "http://test" + i + ".com/");
|
||||
Assert.equal(bookmark.tags, "tag" + i);
|
||||
}
|
||||
});
|
||||
98
toolkit/components/places/tests/bookmarks/test_384228.js
Normal file
98
toolkit/components/places/tests/bookmarks/test_384228.js
Normal file
|
|
@ -0,0 +1,98 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim:set ts=2 sw=2 sts=2 et: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/**
|
||||
* test querying for bookmarks in multiple folders.
|
||||
*/
|
||||
add_task(function* search_bookmark_in_folder() {
|
||||
let testFolder1 = yield PlacesUtils.bookmarks.insert({
|
||||
parentGuid: PlacesUtils.bookmarks.unfiledGuid,
|
||||
type: PlacesUtils.bookmarks.TYPE_FOLDER,
|
||||
title: "bug 384228 test folder 1"
|
||||
});
|
||||
Assert.equal(testFolder1.index, 0);
|
||||
|
||||
let testFolder2 = yield PlacesUtils.bookmarks.insert({
|
||||
parentGuid: PlacesUtils.bookmarks.unfiledGuid,
|
||||
type: PlacesUtils.bookmarks.TYPE_FOLDER,
|
||||
title: "bug 384228 test folder 2"
|
||||
});
|
||||
Assert.equal(testFolder2.index, 1);
|
||||
|
||||
let testFolder3 = yield PlacesUtils.bookmarks.insert({
|
||||
parentGuid: PlacesUtils.bookmarks.unfiledGuid,
|
||||
type: PlacesUtils.bookmarks.TYPE_FOLDER,
|
||||
title: "bug 384228 test folder 3"
|
||||
});
|
||||
Assert.equal(testFolder3.index, 2);
|
||||
|
||||
let b1 = yield PlacesUtils.bookmarks.insert({
|
||||
parentGuid: testFolder1.guid,
|
||||
url: "http://foo.tld/",
|
||||
title: "title b1 (folder 1)"
|
||||
});
|
||||
Assert.equal(b1.index, 0);
|
||||
|
||||
let b2 = yield PlacesUtils.bookmarks.insert({
|
||||
parentGuid: testFolder1.guid,
|
||||
url: "http://foo.tld/",
|
||||
title: "title b2 (folder 1)"
|
||||
});
|
||||
Assert.equal(b2.index, 1);
|
||||
|
||||
let b3 = yield PlacesUtils.bookmarks.insert({
|
||||
parentGuid: testFolder2.guid,
|
||||
url: "http://foo.tld/",
|
||||
title: "title b3 (folder 2)"
|
||||
});
|
||||
Assert.equal(b3.index, 0);
|
||||
|
||||
let b4 = yield PlacesUtils.bookmarks.insert({
|
||||
parentGuid: testFolder3.guid,
|
||||
url: "http://foo.tld/",
|
||||
title: "title b4 (folder 3)"
|
||||
});
|
||||
Assert.equal(b4.index, 0);
|
||||
|
||||
// also test recursive search
|
||||
let testFolder1_1 = yield PlacesUtils.bookmarks.insert({
|
||||
parentGuid: testFolder1.guid,
|
||||
type: PlacesUtils.bookmarks.TYPE_FOLDER,
|
||||
title: "bug 384228 test folder 1.1"
|
||||
});
|
||||
Assert.equal(testFolder1_1.index, 2);
|
||||
|
||||
let b5 = yield PlacesUtils.bookmarks.insert({
|
||||
parentGuid: testFolder1_1.guid,
|
||||
url: "http://foo.tld/",
|
||||
title: "title b5 (folder 1.1)"
|
||||
});
|
||||
Assert.equal(b5.index, 0);
|
||||
|
||||
|
||||
// query folder 1, folder 2 and get 4 bookmarks
|
||||
let folderIds = [];
|
||||
folderIds.push(yield PlacesUtils.promiseItemId(testFolder1.guid));
|
||||
folderIds.push(yield PlacesUtils.promiseItemId(testFolder2.guid));
|
||||
|
||||
let hs = PlacesUtils.history;
|
||||
let options = hs.getNewQueryOptions();
|
||||
let query = hs.getNewQuery();
|
||||
query.searchTerms = "title";
|
||||
options.queryType = options.QUERY_TYPE_BOOKMARKS;
|
||||
query.setFolders(folderIds, folderIds.length);
|
||||
let rootNode = hs.executeQuery(query, options).root;
|
||||
rootNode.containerOpen = true;
|
||||
|
||||
// should not match item from folder 3
|
||||
Assert.equal(rootNode.childCount, 4);
|
||||
Assert.equal(rootNode.getChild(0).bookmarkGuid, b1.guid);
|
||||
Assert.equal(rootNode.getChild(1).bookmarkGuid, b2.guid);
|
||||
Assert.equal(rootNode.getChild(2).bookmarkGuid, b3.guid);
|
||||
Assert.equal(rootNode.getChild(3).bookmarkGuid, b5.guid);
|
||||
|
||||
rootNode.containerOpen = false;
|
||||
});
|
||||
182
toolkit/components/places/tests/bookmarks/test_385829.js
Normal file
182
toolkit/components/places/tests/bookmarks/test_385829.js
Normal file
|
|
@ -0,0 +1,182 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim:set ts=2 sw=2 sts=2 et: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
add_task(function* search_bookmark_by_lastModified_dateDated() {
|
||||
// test search on folder with various sorts and max results
|
||||
// see bug #385829 for more details
|
||||
let folder = yield PlacesUtils.bookmarks.insert({
|
||||
parentGuid: PlacesUtils.bookmarks.unfiledGuid,
|
||||
type: PlacesUtils.bookmarks.TYPE_FOLDER,
|
||||
title: "bug 385829 test"
|
||||
});
|
||||
|
||||
let now = new Date();
|
||||
// ensure some unique values for date added and last modified
|
||||
// for date added: b1 < b2 < b3 < b4
|
||||
// for last modified: b1 > b2 > b3 > b4
|
||||
let b1 = yield PlacesUtils.bookmarks.insert({
|
||||
parentGuid: folder.guid,
|
||||
url: "http://a1.com/",
|
||||
title: "1 title",
|
||||
dateAdded: new Date(now.getTime() + 1000)
|
||||
});
|
||||
let b2 = yield PlacesUtils.bookmarks.insert({
|
||||
parentGuid: folder.guid,
|
||||
url: "http://a2.com/",
|
||||
title: "2 title",
|
||||
dateAdded: new Date(now.getTime() + 2000)
|
||||
});
|
||||
let b3 = yield PlacesUtils.bookmarks.insert({
|
||||
parentGuid: folder.guid,
|
||||
url: "http://a3.com/",
|
||||
title: "3 title",
|
||||
dateAdded: new Date(now.getTime() + 3000)
|
||||
});
|
||||
let b4 = yield PlacesUtils.bookmarks.insert({
|
||||
parentGuid: folder.guid,
|
||||
url: "http://a4.com/",
|
||||
title: "4 title",
|
||||
dateAdded: new Date(now.getTime() + 4000)
|
||||
});
|
||||
|
||||
// make sure lastModified is larger than dateAdded
|
||||
let modifiedTime = new Date(now.getTime() + 5000);
|
||||
yield PlacesUtils.bookmarks.update({
|
||||
guid: b1.guid,
|
||||
lastModified: new Date(modifiedTime.getTime() + 4000)
|
||||
});
|
||||
yield PlacesUtils.bookmarks.update({
|
||||
guid: b2.guid,
|
||||
lastModified: new Date(modifiedTime.getTime() + 3000)
|
||||
});
|
||||
yield PlacesUtils.bookmarks.update({
|
||||
guid: b3.guid,
|
||||
lastModified: new Date(modifiedTime.getTime() + 2000)
|
||||
});
|
||||
yield PlacesUtils.bookmarks.update({
|
||||
guid: b4.guid,
|
||||
lastModified: new Date(modifiedTime.getTime() + 1000)
|
||||
});
|
||||
|
||||
let hs = PlacesUtils.history;
|
||||
let options = hs.getNewQueryOptions();
|
||||
let query = hs.getNewQuery();
|
||||
options.queryType = options.QUERY_TYPE_BOOKMARKS;
|
||||
options.maxResults = 3;
|
||||
let folderIds = [];
|
||||
folderIds.push(yield PlacesUtils.promiseItemId(folder.guid));
|
||||
query.setFolders(folderIds, 1);
|
||||
|
||||
let result = hs.executeQuery(query, options);
|
||||
let rootNode = result.root;
|
||||
rootNode.containerOpen = true;
|
||||
|
||||
// test SORT_BY_DATEADDED_ASCENDING (live update)
|
||||
result.sortingMode = options.SORT_BY_DATEADDED_ASCENDING;
|
||||
Assert.equal(rootNode.childCount, 3);
|
||||
Assert.equal(rootNode.getChild(0).bookmarkGuid, b1.guid);
|
||||
Assert.equal(rootNode.getChild(1).bookmarkGuid, b2.guid);
|
||||
Assert.equal(rootNode.getChild(2).bookmarkGuid, b3.guid);
|
||||
Assert.ok(rootNode.getChild(0).dateAdded <
|
||||
rootNode.getChild(1).dateAdded);
|
||||
Assert.ok(rootNode.getChild(1).dateAdded <
|
||||
rootNode.getChild(2).dateAdded);
|
||||
|
||||
// test SORT_BY_DATEADDED_DESCENDING (live update)
|
||||
result.sortingMode = options.SORT_BY_DATEADDED_DESCENDING;
|
||||
Assert.equal(rootNode.childCount, 3);
|
||||
Assert.equal(rootNode.getChild(0).bookmarkGuid, b3.guid);
|
||||
Assert.equal(rootNode.getChild(1).bookmarkGuid, b2.guid);
|
||||
Assert.equal(rootNode.getChild(2).bookmarkGuid, b1.guid);
|
||||
Assert.ok(rootNode.getChild(0).dateAdded >
|
||||
rootNode.getChild(1).dateAdded);
|
||||
Assert.ok(rootNode.getChild(1).dateAdded >
|
||||
rootNode.getChild(2).dateAdded);
|
||||
|
||||
// test SORT_BY_LASTMODIFIED_ASCENDING (live update)
|
||||
result.sortingMode = options.SORT_BY_LASTMODIFIED_ASCENDING;
|
||||
Assert.equal(rootNode.childCount, 3);
|
||||
Assert.equal(rootNode.getChild(0).bookmarkGuid, b3.guid);
|
||||
Assert.equal(rootNode.getChild(1).bookmarkGuid, b2.guid);
|
||||
Assert.equal(rootNode.getChild(2).bookmarkGuid, b1.guid);
|
||||
Assert.ok(rootNode.getChild(0).lastModified <
|
||||
rootNode.getChild(1).lastModified);
|
||||
Assert.ok(rootNode.getChild(1).lastModified <
|
||||
rootNode.getChild(2).lastModified);
|
||||
|
||||
// test SORT_BY_LASTMODIFIED_DESCENDING (live update)
|
||||
result.sortingMode = options.SORT_BY_LASTMODIFIED_DESCENDING;
|
||||
|
||||
Assert.equal(rootNode.childCount, 3);
|
||||
Assert.equal(rootNode.getChild(0).bookmarkGuid, b1.guid);
|
||||
Assert.equal(rootNode.getChild(1).bookmarkGuid, b2.guid);
|
||||
Assert.equal(rootNode.getChild(2).bookmarkGuid, b3.guid);
|
||||
Assert.ok(rootNode.getChild(0).lastModified >
|
||||
rootNode.getChild(1).lastModified);
|
||||
Assert.ok(rootNode.getChild(1).lastModified >
|
||||
rootNode.getChild(2).lastModified);
|
||||
rootNode.containerOpen = false;
|
||||
|
||||
// test SORT_BY_DATEADDED_ASCENDING
|
||||
options.sortingMode = options.SORT_BY_DATEADDED_ASCENDING;
|
||||
result = hs.executeQuery(query, options);
|
||||
rootNode = result.root;
|
||||
rootNode.containerOpen = true;
|
||||
Assert.equal(rootNode.childCount, 3);
|
||||
Assert.equal(rootNode.getChild(0).bookmarkGuid, b1.guid);
|
||||
Assert.equal(rootNode.getChild(1).bookmarkGuid, b2.guid);
|
||||
Assert.equal(rootNode.getChild(2).bookmarkGuid, b3.guid);
|
||||
Assert.ok(rootNode.getChild(0).dateAdded <
|
||||
rootNode.getChild(1).dateAdded);
|
||||
Assert.ok(rootNode.getChild(1).dateAdded <
|
||||
rootNode.getChild(2).dateAdded);
|
||||
rootNode.containerOpen = false;
|
||||
|
||||
// test SORT_BY_DATEADDED_DESCENDING
|
||||
options.sortingMode = options.SORT_BY_DATEADDED_DESCENDING;
|
||||
result = hs.executeQuery(query, options);
|
||||
rootNode = result.root;
|
||||
rootNode.containerOpen = true;
|
||||
Assert.equal(rootNode.childCount, 3);
|
||||
Assert.equal(rootNode.getChild(0).bookmarkGuid, b4.guid);
|
||||
Assert.equal(rootNode.getChild(1).bookmarkGuid, b3.guid);
|
||||
Assert.equal(rootNode.getChild(2).bookmarkGuid, b2.guid);
|
||||
Assert.ok(rootNode.getChild(0).dateAdded >
|
||||
rootNode.getChild(1).dateAdded);
|
||||
Assert.ok(rootNode.getChild(1).dateAdded >
|
||||
rootNode.getChild(2).dateAdded);
|
||||
rootNode.containerOpen = false;
|
||||
|
||||
// test SORT_BY_LASTMODIFIED_ASCENDING
|
||||
options.sortingMode = options.SORT_BY_LASTMODIFIED_ASCENDING;
|
||||
result = hs.executeQuery(query, options);
|
||||
rootNode = result.root;
|
||||
rootNode.containerOpen = true;
|
||||
Assert.equal(rootNode.childCount, 3);
|
||||
Assert.equal(rootNode.getChild(0).bookmarkGuid, b4.guid);
|
||||
Assert.equal(rootNode.getChild(1).bookmarkGuid, b3.guid);
|
||||
Assert.equal(rootNode.getChild(2).bookmarkGuid, b2.guid);
|
||||
Assert.ok(rootNode.getChild(0).lastModified <
|
||||
rootNode.getChild(1).lastModified);
|
||||
Assert.ok(rootNode.getChild(1).lastModified <
|
||||
rootNode.getChild(2).lastModified);
|
||||
rootNode.containerOpen = false;
|
||||
|
||||
// test SORT_BY_LASTMODIFIED_DESCENDING
|
||||
options.sortingMode = options.SORT_BY_LASTMODIFIED_DESCENDING;
|
||||
result = hs.executeQuery(query, options);
|
||||
rootNode = result.root;
|
||||
rootNode.containerOpen = true;
|
||||
Assert.equal(rootNode.childCount, 3);
|
||||
Assert.equal(rootNode.getChild(0).bookmarkGuid, b1.guid);
|
||||
Assert.equal(rootNode.getChild(1).bookmarkGuid, b2.guid);
|
||||
Assert.equal(rootNode.getChild(2).bookmarkGuid, b3.guid);
|
||||
Assert.ok(rootNode.getChild(0).lastModified >
|
||||
rootNode.getChild(1).lastModified);
|
||||
Assert.ok(rootNode.getChild(1).lastModified >
|
||||
rootNode.getChild(2).lastModified);
|
||||
rootNode.containerOpen = false;
|
||||
});
|
||||
52
toolkit/components/places/tests/bookmarks/test_388695.js
Normal file
52
toolkit/components/places/tests/bookmarks/test_388695.js
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim:set ts=2 sw=2 sts=2 et: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
// Get bookmark service
|
||||
try {
|
||||
var bmsvc = Cc["@mozilla.org/browser/nav-bookmarks-service;1"].
|
||||
getService(Ci.nsINavBookmarksService);
|
||||
} catch (ex) {
|
||||
do_throw("Could not get nav-bookmarks-service\n");
|
||||
}
|
||||
|
||||
var gTestRoot;
|
||||
var gURI;
|
||||
var gItemId1;
|
||||
var gItemId2;
|
||||
|
||||
// main
|
||||
function run_test() {
|
||||
gURI = uri("http://foo.tld.com/");
|
||||
gTestRoot = bmsvc.createFolder(bmsvc.placesRoot, "test folder",
|
||||
bmsvc.DEFAULT_INDEX);
|
||||
|
||||
// test getBookmarkIdsForURI
|
||||
// getBookmarkIdsForURI sorts by the most recently added/modified (descending)
|
||||
//
|
||||
// we cannot rely on dateAdded growing when doing so in a simple iteration,
|
||||
// see PR_Now() documentation
|
||||
do_test_pending();
|
||||
|
||||
gItemId1 = bmsvc.insertBookmark(gTestRoot, gURI, bmsvc.DEFAULT_INDEX, "");
|
||||
do_timeout(100, phase2);
|
||||
}
|
||||
|
||||
function phase2() {
|
||||
gItemId2 = bmsvc.insertBookmark(gTestRoot, gURI, bmsvc.DEFAULT_INDEX, "");
|
||||
var b = bmsvc.getBookmarkIdsForURI(gURI);
|
||||
do_check_eq(b[0], gItemId2);
|
||||
do_check_eq(b[1], gItemId1);
|
||||
do_timeout(100, phase3);
|
||||
}
|
||||
|
||||
function phase3() {
|
||||
// trigger last modified change
|
||||
bmsvc.setItemTitle(gItemId1, "");
|
||||
var b = bmsvc.getBookmarkIdsForURI(gURI);
|
||||
do_check_eq(b[0], gItemId1);
|
||||
do_check_eq(b[1], gItemId2);
|
||||
do_test_finished();
|
||||
}
|
||||
102
toolkit/components/places/tests/bookmarks/test_393498.js
Normal file
102
toolkit/components/places/tests/bookmarks/test_393498.js
Normal file
|
|
@ -0,0 +1,102 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim:set ts=2 sw=2 sts=2 et: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
var observer = {
|
||||
__proto__: NavBookmarkObserver.prototype,
|
||||
|
||||
onItemAdded: function (id, folder, index) {
|
||||
this._itemAddedId = id;
|
||||
this._itemAddedParent = folder;
|
||||
this._itemAddedIndex = index;
|
||||
},
|
||||
onItemChanged: function (id, property, isAnnotationProperty, value) {
|
||||
this._itemChangedId = id;
|
||||
this._itemChangedProperty = property;
|
||||
this._itemChanged_isAnnotationProperty = isAnnotationProperty;
|
||||
this._itemChangedValue = value;
|
||||
}
|
||||
};
|
||||
PlacesUtils.bookmarks.addObserver(observer, false);
|
||||
|
||||
do_register_cleanup(function () {
|
||||
PlacesUtils.bookmarks.removeObserver(observer);
|
||||
});
|
||||
|
||||
function run_test() {
|
||||
// We set times in the past to workaround a timing bug due to virtual
|
||||
// machines and the skew between PR_Now() and Date.now(), see bug 427142 and
|
||||
// bug 858377 for details.
|
||||
const PAST_PRTIME = (Date.now() - 86400000) * 1000;
|
||||
|
||||
// Insert a new bookmark.
|
||||
let testFolder = PlacesUtils.bookmarks.createFolder(
|
||||
PlacesUtils.placesRootId, "test Folder",
|
||||
PlacesUtils.bookmarks.DEFAULT_INDEX);
|
||||
let bookmarkId = PlacesUtils.bookmarks.insertBookmark(
|
||||
testFolder, uri("http://google.com/"),
|
||||
PlacesUtils.bookmarks.DEFAULT_INDEX, "");
|
||||
|
||||
// Sanity check.
|
||||
do_check_true(observer.itemChangedProperty === undefined);
|
||||
|
||||
// Set dateAdded in the past and verify the bookmarks cache.
|
||||
PlacesUtils.bookmarks.setItemDateAdded(bookmarkId, PAST_PRTIME);
|
||||
do_check_eq(observer._itemChangedProperty, "dateAdded");
|
||||
do_check_eq(observer._itemChangedValue, PAST_PRTIME);
|
||||
let dateAdded = PlacesUtils.bookmarks.getItemDateAdded(bookmarkId);
|
||||
do_check_eq(dateAdded, PAST_PRTIME);
|
||||
|
||||
// After just inserting, modified should be the same as dateAdded.
|
||||
do_check_eq(PlacesUtils.bookmarks.getItemLastModified(bookmarkId), dateAdded);
|
||||
|
||||
// Set lastModified in the past and verify the bookmarks cache.
|
||||
PlacesUtils.bookmarks.setItemLastModified(bookmarkId, PAST_PRTIME);
|
||||
do_check_eq(observer._itemChangedProperty, "lastModified");
|
||||
do_check_eq(observer._itemChangedValue, PAST_PRTIME);
|
||||
do_check_eq(PlacesUtils.bookmarks.getItemLastModified(bookmarkId),
|
||||
PAST_PRTIME);
|
||||
|
||||
// Set bookmark title
|
||||
PlacesUtils.bookmarks.setItemTitle(bookmarkId, "Google");
|
||||
|
||||
// Test notifications.
|
||||
do_check_eq(observer._itemChangedId, bookmarkId);
|
||||
do_check_eq(observer._itemChangedProperty, "title");
|
||||
do_check_eq(observer._itemChangedValue, "Google");
|
||||
|
||||
// Check lastModified has been updated.
|
||||
is_time_ordered(PAST_PRTIME,
|
||||
PlacesUtils.bookmarks.getItemLastModified(bookmarkId));
|
||||
|
||||
// Check that node properties are updated.
|
||||
let root = PlacesUtils.getFolderContents(testFolder).root;
|
||||
do_check_eq(root.childCount, 1);
|
||||
let childNode = root.getChild(0);
|
||||
|
||||
// confirm current dates match node properties
|
||||
do_check_eq(PlacesUtils.bookmarks.getItemDateAdded(bookmarkId),
|
||||
childNode.dateAdded);
|
||||
do_check_eq(PlacesUtils.bookmarks.getItemLastModified(bookmarkId),
|
||||
childNode.lastModified);
|
||||
|
||||
// Test live update of lastModified when setting title.
|
||||
PlacesUtils.bookmarks.setItemLastModified(bookmarkId, PAST_PRTIME);
|
||||
PlacesUtils.bookmarks.setItemTitle(bookmarkId, "Google");
|
||||
|
||||
// Check lastModified has been updated.
|
||||
is_time_ordered(PAST_PRTIME, childNode.lastModified);
|
||||
// Test that node value matches db value.
|
||||
do_check_eq(PlacesUtils.bookmarks.getItemLastModified(bookmarkId),
|
||||
childNode.lastModified);
|
||||
|
||||
// Test live update of the exposed date apis.
|
||||
PlacesUtils.bookmarks.setItemDateAdded(bookmarkId, PAST_PRTIME);
|
||||
do_check_eq(childNode.dateAdded, PAST_PRTIME);
|
||||
PlacesUtils.bookmarks.setItemLastModified(bookmarkId, PAST_PRTIME);
|
||||
do_check_eq(childNode.lastModified, PAST_PRTIME);
|
||||
|
||||
root.containerOpen = false;
|
||||
}
|
||||
87
toolkit/components/places/tests/bookmarks/test_395101.js
Normal file
87
toolkit/components/places/tests/bookmarks/test_395101.js
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim:set ts=2 sw=2 sts=2 et: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
// Get bookmark service
|
||||
try {
|
||||
var bmsvc = Cc["@mozilla.org/browser/nav-bookmarks-service;1"].getService(Ci.nsINavBookmarksService);
|
||||
} catch (ex) {
|
||||
do_throw("Could not get nav-bookmarks-service\n");
|
||||
}
|
||||
|
||||
// Get history service
|
||||
try {
|
||||
var histsvc = Cc["@mozilla.org/browser/nav-history-service;1"].getService(Ci.nsINavHistoryService);
|
||||
} catch (ex) {
|
||||
do_throw("Could not get history service\n");
|
||||
}
|
||||
|
||||
// Get tagging service
|
||||
try {
|
||||
var tagssvc = Cc["@mozilla.org/browser/tagging-service;1"].
|
||||
getService(Ci.nsITaggingService);
|
||||
} catch (ex) {
|
||||
do_throw("Could not get tagging service\n");
|
||||
}
|
||||
|
||||
// get bookmarks root id
|
||||
var root = bmsvc.bookmarksMenuFolder;
|
||||
|
||||
// main
|
||||
function run_test() {
|
||||
// test searching for tagged bookmarks
|
||||
|
||||
// test folder
|
||||
var folder = bmsvc.createFolder(root, "bug 395101 test", bmsvc.DEFAULT_INDEX);
|
||||
|
||||
// create a bookmark
|
||||
var testURI = uri("http://a1.com");
|
||||
var b1 = bmsvc.insertBookmark(folder, testURI,
|
||||
bmsvc.DEFAULT_INDEX, "1 title");
|
||||
|
||||
// tag the bookmarked URI
|
||||
tagssvc.tagURI(testURI, ["elephant", "walrus", "giraffe", "turkey", "hiPPo", "BABOON", "alf"]);
|
||||
|
||||
// search for the bookmark, using a tag
|
||||
var query = histsvc.getNewQuery();
|
||||
query.searchTerms = "elephant";
|
||||
var options = histsvc.getNewQueryOptions();
|
||||
options.queryType = Ci.nsINavHistoryQueryOptions.QUERY_TYPE_BOOKMARKS;
|
||||
query.setFolders([folder], 1);
|
||||
|
||||
var result = histsvc.executeQuery(query, options);
|
||||
var rootNode = result.root;
|
||||
rootNode.containerOpen = true;
|
||||
|
||||
do_check_eq(rootNode.childCount, 1);
|
||||
do_check_eq(rootNode.getChild(0).itemId, b1);
|
||||
rootNode.containerOpen = false;
|
||||
|
||||
// partial matches are okay
|
||||
query.searchTerms = "wal";
|
||||
result = histsvc.executeQuery(query, options);
|
||||
rootNode = result.root;
|
||||
rootNode.containerOpen = true;
|
||||
do_check_eq(rootNode.childCount, 1);
|
||||
rootNode.containerOpen = false;
|
||||
|
||||
// case insensitive search term
|
||||
query.searchTerms = "WALRUS";
|
||||
result = histsvc.executeQuery(query, options);
|
||||
rootNode = result.root;
|
||||
rootNode.containerOpen = true;
|
||||
do_check_eq(rootNode.childCount, 1);
|
||||
do_check_eq(rootNode.getChild(0).itemId, b1);
|
||||
rootNode.containerOpen = false;
|
||||
|
||||
// case insensitive tag
|
||||
query.searchTerms = "baboon";
|
||||
result = histsvc.executeQuery(query, options);
|
||||
rootNode = result.root;
|
||||
rootNode.containerOpen = true;
|
||||
do_check_eq(rootNode.childCount, 1);
|
||||
do_check_eq(rootNode.getChild(0).itemId, b1);
|
||||
rootNode.containerOpen = false;
|
||||
}
|
||||
69
toolkit/components/places/tests/bookmarks/test_395593.js
Normal file
69
toolkit/components/places/tests/bookmarks/test_395593.js
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim:set ts=2 sw=2 sts=2 et: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
|
||||
var bs = Cc["@mozilla.org/browser/nav-bookmarks-service;1"].
|
||||
getService(Ci.nsINavBookmarksService);
|
||||
var hs = Cc["@mozilla.org/browser/nav-history-service;1"].
|
||||
getService(Ci.nsINavHistoryService);
|
||||
|
||||
function check_queries_results(aQueries, aOptions, aExpectedItemIds) {
|
||||
var result = hs.executeQueries(aQueries, aQueries.length, aOptions);
|
||||
var root = result.root;
|
||||
root.containerOpen = true;
|
||||
|
||||
// Dump found nodes.
|
||||
for (let i = 0; i < root.childCount; i++) {
|
||||
dump("nodes[" + i + "]: " + root.getChild(0).title + "\n");
|
||||
}
|
||||
|
||||
do_check_eq(root.childCount, aExpectedItemIds.length);
|
||||
for (let i = 0; i < root.childCount; i++) {
|
||||
do_check_eq(root.getChild(i).itemId, aExpectedItemIds[i]);
|
||||
}
|
||||
|
||||
root.containerOpen = false;
|
||||
}
|
||||
|
||||
// main
|
||||
function run_test() {
|
||||
var id1 = bs.insertBookmark(bs.bookmarksMenuFolder, uri("http://foo.tld"),
|
||||
bs.DEFAULT_INDEX, "123 0");
|
||||
var id2 = bs.insertBookmark(bs.bookmarksMenuFolder, uri("http://foo.tld"),
|
||||
bs.DEFAULT_INDEX, "456");
|
||||
var id3 = bs.insertBookmark(bs.bookmarksMenuFolder, uri("http://foo.tld"),
|
||||
bs.DEFAULT_INDEX, "123 456");
|
||||
var id4 = bs.insertBookmark(bs.bookmarksMenuFolder, uri("http://foo.tld"),
|
||||
bs.DEFAULT_INDEX, "789 456");
|
||||
|
||||
/**
|
||||
* All of the query objects are ORed together. Within a query, all the terms
|
||||
* are ANDed together. See nsINavHistory.idl.
|
||||
*/
|
||||
var queries = [];
|
||||
queries.push(hs.getNewQuery());
|
||||
queries.push(hs.getNewQuery());
|
||||
var options = hs.getNewQueryOptions();
|
||||
options.queryType = Ci.nsINavHistoryQueryOptions.QUERY_TYPE_BOOKMARKS;
|
||||
|
||||
// Test 1
|
||||
dump("Test searching for 123 OR 789\n");
|
||||
queries[0].searchTerms = "123";
|
||||
queries[1].searchTerms = "789";
|
||||
check_queries_results(queries, options, [id1, id3, id4]);
|
||||
|
||||
// Test 2
|
||||
dump("Test searching for 123 OR 456\n");
|
||||
queries[0].searchTerms = "123";
|
||||
queries[1].searchTerms = "456";
|
||||
check_queries_results(queries, options, [id1, id2, id3, id4]);
|
||||
|
||||
// Test 3
|
||||
dump("Test searching for 00 OR 789\n");
|
||||
queries[0].searchTerms = "00";
|
||||
queries[1].searchTerms = "789";
|
||||
check_queries_results(queries, options, [id4]);
|
||||
}
|
||||
|
|
@ -0,0 +1,221 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim:set ts=2 sw=2 sts=2 et: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
var tests = [];
|
||||
|
||||
/*
|
||||
|
||||
Backup/restore tests example:
|
||||
|
||||
var myTest = {
|
||||
populate: function () { ... add bookmarks ... },
|
||||
validate: function () { ... query for your bookmarks ... }
|
||||
}
|
||||
|
||||
this.push(myTest);
|
||||
|
||||
*/
|
||||
|
||||
/*
|
||||
|
||||
test summary:
|
||||
- create folders with content
|
||||
- create a query bookmark for those folders
|
||||
- backs up bookmarks
|
||||
- restores bookmarks
|
||||
- confirms that the query has the new ids for the same folders
|
||||
|
||||
scenarios:
|
||||
- 1 folder (folder shortcut)
|
||||
- n folders (single query)
|
||||
- n folders (multiple queries)
|
||||
|
||||
*/
|
||||
|
||||
const DEFAULT_INDEX = PlacesUtils.bookmarks.DEFAULT_INDEX;
|
||||
|
||||
var test = {
|
||||
_testRootId: null,
|
||||
_testRootTitle: "test root",
|
||||
_folderIds: [],
|
||||
_bookmarkURIs: [],
|
||||
_count: 3,
|
||||
|
||||
populate: function populate() {
|
||||
// folder to hold this test
|
||||
PlacesUtils.bookmarks.removeFolderChildren(PlacesUtils.toolbarFolderId);
|
||||
this._testRootId =
|
||||
PlacesUtils.bookmarks.createFolder(PlacesUtils.toolbarFolderId,
|
||||
this._testRootTitle, DEFAULT_INDEX);
|
||||
|
||||
// create test folders each with a bookmark
|
||||
for (var i = 0; i < this._count; i++) {
|
||||
var folderId =
|
||||
PlacesUtils.bookmarks.createFolder(this._testRootId, "folder" + i, DEFAULT_INDEX);
|
||||
this._folderIds.push(folderId)
|
||||
|
||||
var bookmarkURI = uri("http://" + i);
|
||||
PlacesUtils.bookmarks.insertBookmark(folderId, bookmarkURI,
|
||||
DEFAULT_INDEX, "bookmark" + i);
|
||||
this._bookmarkURIs.push(bookmarkURI);
|
||||
}
|
||||
|
||||
// create a query URI with 1 folder (ie: folder shortcut)
|
||||
this._queryURI1 = uri("place:folder=" + this._folderIds[0] + "&queryType=1");
|
||||
this._queryTitle1 = "query1";
|
||||
PlacesUtils.bookmarks.insertBookmark(this._testRootId, this._queryURI1,
|
||||
DEFAULT_INDEX, this._queryTitle1);
|
||||
|
||||
// create a query URI with _count folders
|
||||
this._queryURI2 = uri("place:folder=" + this._folderIds.join("&folder=") + "&queryType=1");
|
||||
this._queryTitle2 = "query2";
|
||||
PlacesUtils.bookmarks.insertBookmark(this._testRootId, this._queryURI2,
|
||||
DEFAULT_INDEX, this._queryTitle2);
|
||||
|
||||
// create a query URI with _count queries (each with a folder)
|
||||
// first get a query object for each folder
|
||||
var queries = this._folderIds.map(function(aFolderId) {
|
||||
var query = PlacesUtils.history.getNewQuery();
|
||||
query.setFolders([aFolderId], 1);
|
||||
return query;
|
||||
});
|
||||
var options = PlacesUtils.history.getNewQueryOptions();
|
||||
options.queryType = options.QUERY_TYPE_BOOKMARKS;
|
||||
this._queryURI3 =
|
||||
uri(PlacesUtils.history.queriesToQueryString(queries, queries.length, options));
|
||||
this._queryTitle3 = "query3";
|
||||
PlacesUtils.bookmarks.insertBookmark(this._testRootId, this._queryURI3,
|
||||
DEFAULT_INDEX, this._queryTitle3);
|
||||
},
|
||||
|
||||
clean: function () {},
|
||||
|
||||
validate: function validate() {
|
||||
// Throw a wrench in the works by inserting some new bookmarks,
|
||||
// ensuring folder ids won't be the same, when restoring.
|
||||
for (let i = 0; i < 10; i++) {
|
||||
PlacesUtils.bookmarks.
|
||||
insertBookmark(PlacesUtils.bookmarksMenuFolderId, uri("http://aaaa"+i), DEFAULT_INDEX, "");
|
||||
}
|
||||
|
||||
var toolbar =
|
||||
PlacesUtils.getFolderContents(PlacesUtils.toolbarFolderId,
|
||||
false, true).root;
|
||||
do_check_true(toolbar.childCount, 1);
|
||||
|
||||
var folderNode = toolbar.getChild(0);
|
||||
do_check_eq(folderNode.type, folderNode.RESULT_TYPE_FOLDER);
|
||||
do_check_eq(folderNode.title, this._testRootTitle);
|
||||
folderNode.QueryInterface(Ci.nsINavHistoryQueryResultNode);
|
||||
folderNode.containerOpen = true;
|
||||
|
||||
// |_count| folders + the query node
|
||||
do_check_eq(folderNode.childCount, this._count+3);
|
||||
|
||||
for (let i = 0; i < this._count; i++) {
|
||||
var subFolder = folderNode.getChild(i);
|
||||
do_check_eq(subFolder.title, "folder"+i);
|
||||
subFolder.QueryInterface(Ci.nsINavHistoryContainerResultNode);
|
||||
subFolder.containerOpen = true;
|
||||
do_check_eq(subFolder.childCount, 1);
|
||||
var child = subFolder.getChild(0);
|
||||
do_check_eq(child.title, "bookmark"+i);
|
||||
do_check_true(uri(child.uri).equals(uri("http://" + i)))
|
||||
}
|
||||
|
||||
// validate folder shortcut
|
||||
this.validateQueryNode1(folderNode.getChild(this._count));
|
||||
|
||||
// validate folders query
|
||||
this.validateQueryNode2(folderNode.getChild(this._count + 1));
|
||||
|
||||
// validate multiple queries query
|
||||
this.validateQueryNode3(folderNode.getChild(this._count + 2));
|
||||
|
||||
// clean up
|
||||
folderNode.containerOpen = false;
|
||||
toolbar.containerOpen = false;
|
||||
},
|
||||
|
||||
validateQueryNode1: function validateQueryNode1(aNode) {
|
||||
do_check_eq(aNode.title, this._queryTitle1);
|
||||
do_check_true(PlacesUtils.nodeIsFolder(aNode));
|
||||
|
||||
aNode.QueryInterface(Ci.nsINavHistoryContainerResultNode);
|
||||
aNode.containerOpen = true;
|
||||
do_check_eq(aNode.childCount, 1);
|
||||
var child = aNode.getChild(0);
|
||||
do_check_true(uri(child.uri).equals(uri("http://0")))
|
||||
do_check_eq(child.title, "bookmark0")
|
||||
aNode.containerOpen = false;
|
||||
},
|
||||
|
||||
validateQueryNode2: function validateQueryNode2(aNode) {
|
||||
do_check_eq(aNode.title, this._queryTitle2);
|
||||
do_check_true(PlacesUtils.nodeIsQuery(aNode));
|
||||
|
||||
aNode.QueryInterface(Ci.nsINavHistoryContainerResultNode);
|
||||
aNode.containerOpen = true;
|
||||
do_check_eq(aNode.childCount, this._count);
|
||||
for (var i = 0; i < aNode.childCount; i++) {
|
||||
var child = aNode.getChild(i);
|
||||
do_check_true(uri(child.uri).equals(uri("http://" + i)))
|
||||
do_check_eq(child.title, "bookmark" + i)
|
||||
}
|
||||
aNode.containerOpen = false;
|
||||
},
|
||||
|
||||
validateQueryNode3: function validateQueryNode3(aNode) {
|
||||
do_check_eq(aNode.title, this._queryTitle3);
|
||||
do_check_true(PlacesUtils.nodeIsQuery(aNode));
|
||||
|
||||
aNode.QueryInterface(Ci.nsINavHistoryContainerResultNode);
|
||||
aNode.containerOpen = true;
|
||||
do_check_eq(aNode.childCount, this._count);
|
||||
for (var i = 0; i < aNode.childCount; i++) {
|
||||
var child = aNode.getChild(i);
|
||||
do_check_true(uri(child.uri).equals(uri("http://" + i)))
|
||||
do_check_eq(child.title, "bookmark" + i)
|
||||
}
|
||||
aNode.containerOpen = false;
|
||||
}
|
||||
}
|
||||
tests.push(test);
|
||||
|
||||
function run_test() {
|
||||
run_next_test();
|
||||
}
|
||||
|
||||
add_task(function* () {
|
||||
// make json file
|
||||
let jsonFile = OS.Path.join(OS.Constants.Path.profileDir, "bookmarks.json");
|
||||
|
||||
// populate db
|
||||
tests.forEach(function(aTest) {
|
||||
aTest.populate();
|
||||
// sanity
|
||||
aTest.validate();
|
||||
});
|
||||
|
||||
// export json to file
|
||||
yield BookmarkJSONUtils.exportToFile(jsonFile);
|
||||
|
||||
// clean
|
||||
tests.forEach(function(aTest) {
|
||||
aTest.clean();
|
||||
});
|
||||
|
||||
// restore json file
|
||||
yield BookmarkJSONUtils.importFromFile(jsonFile, true);
|
||||
|
||||
// validate
|
||||
tests.forEach(function(aTest) {
|
||||
aTest.validate();
|
||||
});
|
||||
|
||||
// clean up
|
||||
yield OS.File.remove(jsonFile);
|
||||
});
|
||||
|
|
@ -0,0 +1,141 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim:set ts=2 sw=2 sts=2 et: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
const EXCLUDE_FROM_BACKUP_ANNO = "places/excludeFromBackup";
|
||||
// Menu, Toolbar, Unsorted, Tags, Mobile
|
||||
const PLACES_ROOTS_COUNT = 5;
|
||||
var tests = [];
|
||||
|
||||
/*
|
||||
|
||||
Backup/restore tests example:
|
||||
|
||||
var myTest = {
|
||||
populate: function () { ... add bookmarks ... },
|
||||
validate: function () { ... query for your bookmarks ... }
|
||||
}
|
||||
|
||||
this.push(myTest);
|
||||
|
||||
*/
|
||||
|
||||
var test = {
|
||||
populate: function populate() {
|
||||
// check initial size
|
||||
var rootNode = PlacesUtils.getFolderContents(PlacesUtils.placesRootId,
|
||||
false, false).root;
|
||||
do_check_eq(rootNode.childCount, PLACES_ROOTS_COUNT );
|
||||
rootNode.containerOpen = false;
|
||||
|
||||
var idx = PlacesUtils.bookmarks.DEFAULT_INDEX;
|
||||
|
||||
// create a root to be restore
|
||||
this._restoreRootTitle = "restore root";
|
||||
var restoreRootId = PlacesUtils.bookmarks
|
||||
.createFolder(PlacesUtils.placesRootId,
|
||||
this._restoreRootTitle, idx);
|
||||
// add a test bookmark
|
||||
this._restoreRootURI = uri("http://restore.uri");
|
||||
PlacesUtils.bookmarks.insertBookmark(restoreRootId, this._restoreRootURI,
|
||||
idx, "restore uri");
|
||||
// add a test bookmark to be exclude
|
||||
this._restoreRootExcludeURI = uri("http://exclude.uri");
|
||||
var exItemId = PlacesUtils.bookmarks
|
||||
.insertBookmark(restoreRootId,
|
||||
this._restoreRootExcludeURI,
|
||||
idx, "exclude uri");
|
||||
// Annotate the bookmark for exclusion.
|
||||
PlacesUtils.annotations.setItemAnnotation(exItemId,
|
||||
EXCLUDE_FROM_BACKUP_ANNO, 1, 0,
|
||||
PlacesUtils.annotations.EXPIRE_NEVER);
|
||||
|
||||
// create a root to be exclude
|
||||
this._excludeRootTitle = "exclude root";
|
||||
this._excludeRootId = PlacesUtils.bookmarks
|
||||
.createFolder(PlacesUtils.placesRootId,
|
||||
this._excludeRootTitle, idx);
|
||||
// Annotate the root for exclusion.
|
||||
PlacesUtils.annotations.setItemAnnotation(this._excludeRootId,
|
||||
EXCLUDE_FROM_BACKUP_ANNO, 1, 0,
|
||||
PlacesUtils.annotations.EXPIRE_NEVER);
|
||||
// add a test bookmark exclude by exclusion of its parent
|
||||
PlacesUtils.bookmarks.insertBookmark(this._excludeRootId,
|
||||
this._restoreRootExcludeURI,
|
||||
idx, "exclude uri");
|
||||
},
|
||||
|
||||
validate: function validate(aEmptyBookmarks) {
|
||||
var rootNode = PlacesUtils.getFolderContents(PlacesUtils.placesRootId,
|
||||
false, false).root;
|
||||
|
||||
if (!aEmptyBookmarks) {
|
||||
// since restore does not remove backup exclude items both
|
||||
// roots should still exist.
|
||||
do_check_eq(rootNode.childCount, PLACES_ROOTS_COUNT + 2);
|
||||
// open exclude root and check it still contains one item
|
||||
var restoreRootIndex = PLACES_ROOTS_COUNT;
|
||||
var excludeRootIndex = PLACES_ROOTS_COUNT+1;
|
||||
var excludeRootNode = rootNode.getChild(excludeRootIndex);
|
||||
do_check_eq(this._excludeRootTitle, excludeRootNode.title);
|
||||
excludeRootNode.QueryInterface(Ci.nsINavHistoryQueryResultNode);
|
||||
excludeRootNode.containerOpen = true;
|
||||
do_check_eq(excludeRootNode.childCount, 1);
|
||||
var excludeRootChildNode = excludeRootNode.getChild(0);
|
||||
do_check_eq(excludeRootChildNode.uri, this._restoreRootExcludeURI.spec);
|
||||
excludeRootNode.containerOpen = false;
|
||||
}
|
||||
else {
|
||||
// exclude root should not exist anymore
|
||||
do_check_eq(rootNode.childCount, PLACES_ROOTS_COUNT + 1);
|
||||
restoreRootIndex = PLACES_ROOTS_COUNT;
|
||||
}
|
||||
|
||||
var restoreRootNode = rootNode.getChild(restoreRootIndex);
|
||||
do_check_eq(this._restoreRootTitle, restoreRootNode.title);
|
||||
restoreRootNode.QueryInterface(Ci.nsINavHistoryQueryResultNode);
|
||||
restoreRootNode.containerOpen = true;
|
||||
do_check_eq(restoreRootNode.childCount, 1);
|
||||
var restoreRootChildNode = restoreRootNode.getChild(0);
|
||||
do_check_eq(restoreRootChildNode.uri, this._restoreRootURI.spec);
|
||||
restoreRootNode.containerOpen = false;
|
||||
|
||||
rootNode.containerOpen = false;
|
||||
}
|
||||
}
|
||||
|
||||
function run_test() {
|
||||
run_next_test();
|
||||
}
|
||||
|
||||
add_task(function*() {
|
||||
// make json file
|
||||
let jsonFile = OS.Path.join(OS.Constants.Path.profileDir, "bookmarks.json");
|
||||
|
||||
// populate db
|
||||
test.populate();
|
||||
|
||||
yield BookmarkJSONUtils.exportToFile(jsonFile);
|
||||
|
||||
// restore json file
|
||||
yield BookmarkJSONUtils.importFromFile(jsonFile, true);
|
||||
|
||||
// validate without removing all bookmarks
|
||||
// restore do not remove backup exclude entries
|
||||
test.validate(false);
|
||||
|
||||
// cleanup
|
||||
yield PlacesUtils.bookmarks.eraseEverything();
|
||||
// manually remove the excluded root
|
||||
PlacesUtils.bookmarks.removeItem(test._excludeRootId);
|
||||
// restore json file
|
||||
yield BookmarkJSONUtils.importFromFile(jsonFile, true);
|
||||
|
||||
// validate after a complete bookmarks cleanup
|
||||
test.validate(true);
|
||||
|
||||
// clean up
|
||||
yield OS.File.remove(jsonFile);
|
||||
});
|
||||
|
|
@ -0,0 +1,158 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim:set ts=2 sw=2 sts=2 et: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
var tests = [];
|
||||
|
||||
/*
|
||||
|
||||
Backup/restore tests example:
|
||||
|
||||
var myTest = {
|
||||
populate: function () { ... add bookmarks ... },
|
||||
validate: function () { ... query for your bookmarks ... }
|
||||
}
|
||||
|
||||
this.push(myTest);
|
||||
|
||||
*/
|
||||
|
||||
tests.push({
|
||||
excludeItemsFromRestore: [],
|
||||
populate: function populate() {
|
||||
// check initial size
|
||||
var rootNode = PlacesUtils.getFolderContents(PlacesUtils.placesRootId,
|
||||
false, false).root;
|
||||
do_check_eq(rootNode.childCount, 5);
|
||||
|
||||
// create a test root
|
||||
this._folderTitle = "test folder";
|
||||
this._folderId =
|
||||
PlacesUtils.bookmarks.createFolder(PlacesUtils.placesRootId,
|
||||
this._folderTitle,
|
||||
PlacesUtils.bookmarks.DEFAULT_INDEX);
|
||||
do_check_eq(rootNode.childCount, 6);
|
||||
|
||||
// add a tag
|
||||
this._testURI = PlacesUtils._uri("http://test");
|
||||
this._tags = ["a", "b"];
|
||||
PlacesUtils.tagging.tagURI(this._testURI, this._tags);
|
||||
|
||||
// add a child to each root, including our test root
|
||||
this._roots = [PlacesUtils.bookmarksMenuFolderId, PlacesUtils.toolbarFolderId,
|
||||
PlacesUtils.unfiledBookmarksFolderId, PlacesUtils.mobileFolderId,
|
||||
this._folderId];
|
||||
this._roots.forEach(function(aRootId) {
|
||||
// clean slate
|
||||
PlacesUtils.bookmarks.removeFolderChildren(aRootId);
|
||||
// add a test bookmark
|
||||
PlacesUtils.bookmarks.insertBookmark(aRootId, this._testURI,
|
||||
PlacesUtils.bookmarks.DEFAULT_INDEX, "test");
|
||||
}, this);
|
||||
|
||||
// add a folder to exclude from replacing during restore
|
||||
// this will still be present post-restore
|
||||
var excludedFolderId =
|
||||
PlacesUtils.bookmarks.createFolder(PlacesUtils.placesRootId,
|
||||
"excluded",
|
||||
PlacesUtils.bookmarks.DEFAULT_INDEX);
|
||||
do_check_eq(rootNode.childCount, 7);
|
||||
this.excludeItemsFromRestore.push(excludedFolderId);
|
||||
|
||||
// add a test bookmark to it
|
||||
PlacesUtils.bookmarks.insertBookmark(excludedFolderId, this._testURI,
|
||||
PlacesUtils.bookmarks.DEFAULT_INDEX, "test");
|
||||
},
|
||||
|
||||
inbetween: function inbetween() {
|
||||
// add some items that should be removed by the restore
|
||||
|
||||
// add a folder
|
||||
this._litterTitle = "otter";
|
||||
PlacesUtils.bookmarks.createFolder(PlacesUtils.placesRootId,
|
||||
this._litterTitle, 0);
|
||||
|
||||
// add some tags
|
||||
PlacesUtils.tagging.tagURI(this._testURI, ["c", "d"]);
|
||||
},
|
||||
|
||||
validate: function validate() {
|
||||
// validate tags restored
|
||||
var tags = PlacesUtils.tagging.getTagsForURI(this._testURI);
|
||||
// also validates that litter tags are gone
|
||||
do_check_eq(this._tags.toString(), tags.toString());
|
||||
|
||||
var rootNode = PlacesUtils.getFolderContents(PlacesUtils.placesRootId,
|
||||
false, false).root;
|
||||
|
||||
// validate litter is gone
|
||||
do_check_neq(rootNode.getChild(0).title, this._litterTitle);
|
||||
|
||||
// test root count is the same
|
||||
do_check_eq(rootNode.childCount, 7);
|
||||
|
||||
var foundTestFolder = 0;
|
||||
for (var i = 0; i < rootNode.childCount; i++) {
|
||||
var node = rootNode.getChild(i);
|
||||
|
||||
do_print("validating " + node.title);
|
||||
if (node.itemId != PlacesUtils.tagsFolderId) {
|
||||
if (node.title == this._folderTitle) {
|
||||
// check the test folder's properties
|
||||
do_check_eq(node.type, node.RESULT_TYPE_FOLDER);
|
||||
do_check_eq(node.title, this._folderTitle);
|
||||
foundTestFolder++;
|
||||
}
|
||||
|
||||
// test contents
|
||||
node.QueryInterface(Ci.nsINavHistoryContainerResultNode).containerOpen = true;
|
||||
do_check_eq(node.childCount, 1);
|
||||
var child = node.getChild(0);
|
||||
do_check_true(PlacesUtils._uri(child.uri).equals(this._testURI));
|
||||
|
||||
// clean up
|
||||
node.containerOpen = false;
|
||||
}
|
||||
}
|
||||
do_check_eq(foundTestFolder, 1);
|
||||
rootNode.containerOpen = false;
|
||||
}
|
||||
});
|
||||
|
||||
function run_test() {
|
||||
run_next_test();
|
||||
}
|
||||
|
||||
add_task(function* () {
|
||||
// make json file
|
||||
let jsonFile = OS.Path.join(OS.Constants.Path.profileDir, "bookmarks.json");
|
||||
|
||||
// populate db
|
||||
tests.forEach(function(aTest) {
|
||||
aTest.populate();
|
||||
// sanity
|
||||
aTest.validate();
|
||||
|
||||
if (aTest.excludedItemsFromRestore)
|
||||
excludedItemsFromRestore = excludedItems.concat(aTest.excludedItemsFromRestore);
|
||||
});
|
||||
|
||||
yield BookmarkJSONUtils.exportToFile(jsonFile);
|
||||
|
||||
tests.forEach(function(aTest) {
|
||||
aTest.inbetween();
|
||||
});
|
||||
|
||||
// restore json file
|
||||
yield BookmarkJSONUtils.importFromFile(jsonFile, true);
|
||||
|
||||
// validate
|
||||
tests.forEach(function(aTest) {
|
||||
aTest.validate();
|
||||
});
|
||||
|
||||
// clean up
|
||||
yield OS.File.remove(jsonFile);
|
||||
});
|
||||
|
|
@ -0,0 +1,91 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim:set ts=2 sw=2 sts=2 et: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
var tests = [];
|
||||
|
||||
/*
|
||||
|
||||
Backup/restore tests example:
|
||||
|
||||
var myTest = {
|
||||
populate: function () { ... add bookmarks ... },
|
||||
validate: function () { ... query for your bookmarks ... }
|
||||
}
|
||||
|
||||
this.push(myTest);
|
||||
|
||||
*/
|
||||
|
||||
var quotesTest = {
|
||||
_folderTitle: '"quoted folder"',
|
||||
_folderId: null,
|
||||
|
||||
populate: function () {
|
||||
this._folderId =
|
||||
PlacesUtils.bookmarks.createFolder(PlacesUtils.toolbarFolderId,
|
||||
this._folderTitle,
|
||||
PlacesUtils.bookmarks.DEFAULT_INDEX);
|
||||
},
|
||||
|
||||
clean: function () {
|
||||
PlacesUtils.bookmarks.removeItem(this._folderId);
|
||||
},
|
||||
|
||||
validate: function () {
|
||||
var query = PlacesUtils.history.getNewQuery();
|
||||
query.setFolders([PlacesUtils.bookmarks.toolbarFolder], 1);
|
||||
var result = PlacesUtils.history.executeQuery(query, PlacesUtils.history.getNewQueryOptions());
|
||||
|
||||
var toolbar = result.root;
|
||||
toolbar.containerOpen = true;
|
||||
|
||||
// test for our quoted folder
|
||||
do_check_true(toolbar.childCount, 1);
|
||||
var folderNode = toolbar.getChild(0);
|
||||
do_check_eq(folderNode.type, folderNode.RESULT_TYPE_FOLDER);
|
||||
do_check_eq(folderNode.title, this._folderTitle);
|
||||
|
||||
// clean up
|
||||
toolbar.containerOpen = false;
|
||||
}
|
||||
}
|
||||
tests.push(quotesTest);
|
||||
|
||||
function run_test() {
|
||||
run_next_test();
|
||||
}
|
||||
|
||||
add_task(function* () {
|
||||
// make json file
|
||||
let jsonFile = OS.Path.join(OS.Constants.Path.profileDir, "bookmarks.json");
|
||||
|
||||
// populate db
|
||||
tests.forEach(function(aTest) {
|
||||
aTest.populate();
|
||||
// sanity
|
||||
aTest.validate();
|
||||
});
|
||||
|
||||
// export json to file
|
||||
yield BookmarkJSONUtils.exportToFile(jsonFile);
|
||||
|
||||
// clean
|
||||
tests.forEach(function(aTest) {
|
||||
aTest.clean();
|
||||
});
|
||||
|
||||
// restore json file
|
||||
yield BookmarkJSONUtils.importFromFile(jsonFile, true);
|
||||
|
||||
// validate
|
||||
tests.forEach(function(aTest) {
|
||||
aTest.validate();
|
||||
});
|
||||
|
||||
// clean up
|
||||
yield OS.File.remove(jsonFile);
|
||||
|
||||
});
|
||||
113
toolkit/components/places/tests/bookmarks/test_448584.js
Normal file
113
toolkit/components/places/tests/bookmarks/test_448584.js
Normal file
|
|
@ -0,0 +1,113 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim:set ts=2 sw=2 sts=2 et: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
var tests = [];
|
||||
|
||||
// Get database connection
|
||||
try {
|
||||
var mDBConn = PlacesUtils.history.QueryInterface(Ci.nsPIPlacesDatabase)
|
||||
.DBConnection;
|
||||
}
|
||||
catch (ex) {
|
||||
do_throw("Could not get database connection\n");
|
||||
}
|
||||
|
||||
/*
|
||||
This test is:
|
||||
- don't try to add invalid uri nodes to a JSON backup
|
||||
*/
|
||||
|
||||
var invalidURITest = {
|
||||
_itemTitle: "invalid uri",
|
||||
_itemUrl: "http://test.mozilla.org/",
|
||||
_itemId: null,
|
||||
|
||||
populate: function () {
|
||||
// add a valid bookmark
|
||||
PlacesUtils.bookmarks.insertBookmark(PlacesUtils.toolbarFolderId,
|
||||
PlacesUtils._uri(this._itemUrl),
|
||||
PlacesUtils.bookmarks.DEFAULT_INDEX,
|
||||
this._itemTitle);
|
||||
// this bookmark will go corrupt
|
||||
this._itemId =
|
||||
PlacesUtils.bookmarks.insertBookmark(PlacesUtils.toolbarFolderId,
|
||||
PlacesUtils._uri(this._itemUrl),
|
||||
PlacesUtils.bookmarks.DEFAULT_INDEX,
|
||||
this._itemTitle);
|
||||
},
|
||||
|
||||
clean: function () {
|
||||
PlacesUtils.bookmarks.removeItem(this._itemId);
|
||||
},
|
||||
|
||||
validate: function (aExpectValidItemsCount) {
|
||||
var query = PlacesUtils.history.getNewQuery();
|
||||
query.setFolders([PlacesUtils.bookmarks.toolbarFolder], 1);
|
||||
var options = PlacesUtils.history.getNewQueryOptions();
|
||||
var result = PlacesUtils.history.executeQuery(query, options);
|
||||
|
||||
var toolbar = result.root;
|
||||
toolbar.containerOpen = true;
|
||||
|
||||
// test for our bookmark
|
||||
do_check_eq(toolbar.childCount, aExpectValidItemsCount);
|
||||
for (var i = 0; i < toolbar.childCount; i++) {
|
||||
var folderNode = toolbar.getChild(0);
|
||||
do_check_eq(folderNode.type, folderNode.RESULT_TYPE_URI);
|
||||
do_check_eq(folderNode.title, this._itemTitle);
|
||||
}
|
||||
|
||||
// clean up
|
||||
toolbar.containerOpen = false;
|
||||
}
|
||||
}
|
||||
tests.push(invalidURITest);
|
||||
|
||||
function run_test() {
|
||||
run_next_test();
|
||||
}
|
||||
|
||||
add_task(function*() {
|
||||
// make json file
|
||||
let jsonFile = OS.Path.join(OS.Constants.Path.profileDir, "bookmarks.json");
|
||||
|
||||
// populate db
|
||||
tests.forEach(function(aTest) {
|
||||
aTest.populate();
|
||||
// sanity
|
||||
aTest.validate(2);
|
||||
// Something in the code went wrong and we finish up losing the place, so
|
||||
// the bookmark uri becomes null.
|
||||
var sql = "UPDATE moz_bookmarks SET fk = 1337 WHERE id = ?1";
|
||||
var stmt = mDBConn.createStatement(sql);
|
||||
stmt.bindByIndex(0, aTest._itemId);
|
||||
try {
|
||||
stmt.execute();
|
||||
} finally {
|
||||
stmt.finalize();
|
||||
}
|
||||
});
|
||||
|
||||
yield BookmarkJSONUtils.exportToFile(jsonFile);
|
||||
|
||||
// clean
|
||||
tests.forEach(function(aTest) {
|
||||
aTest.clean();
|
||||
});
|
||||
|
||||
// restore json file
|
||||
try {
|
||||
yield BookmarkJSONUtils.importFromFile(jsonFile, true);
|
||||
} catch (ex) { do_throw("couldn't import the exported file: " + ex); }
|
||||
|
||||
// validate
|
||||
tests.forEach(function(aTest) {
|
||||
aTest.validate(1);
|
||||
});
|
||||
|
||||
// clean up
|
||||
yield OS.File.remove(jsonFile);
|
||||
});
|
||||
131
toolkit/components/places/tests/bookmarks/test_458683.js
Normal file
131
toolkit/components/places/tests/bookmarks/test_458683.js
Normal file
|
|
@ -0,0 +1,131 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim:set ts=2 sw=2 sts=2 et: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
var tests = [];
|
||||
|
||||
// Get database connection
|
||||
try {
|
||||
var mDBConn = PlacesUtils.history.QueryInterface(Ci.nsPIPlacesDatabase)
|
||||
.DBConnection;
|
||||
}
|
||||
catch (ex) {
|
||||
do_throw("Could not get database connection\n");
|
||||
}
|
||||
|
||||
/*
|
||||
This test is:
|
||||
- don't block while doing backup and restore if tag containers contain
|
||||
bogus items (separators, folders)
|
||||
*/
|
||||
|
||||
var invalidTagChildTest = {
|
||||
_itemTitle: "invalid uri",
|
||||
_itemUrl: "http://test.mozilla.org/",
|
||||
_itemId: -1,
|
||||
_tag: "testTag",
|
||||
_tagItemId: -1,
|
||||
|
||||
populate: function () {
|
||||
// add a valid bookmark
|
||||
this._itemId = PlacesUtils.bookmarks
|
||||
.insertBookmark(PlacesUtils.toolbarFolderId,
|
||||
PlacesUtils._uri(this._itemUrl),
|
||||
PlacesUtils.bookmarks.DEFAULT_INDEX,
|
||||
this._itemTitle);
|
||||
|
||||
// create a tag
|
||||
PlacesUtils.tagging.tagURI(PlacesUtils._uri(this._itemUrl), [this._tag]);
|
||||
// get tag folder id
|
||||
var options = PlacesUtils.history.getNewQueryOptions();
|
||||
var query = PlacesUtils.history.getNewQuery();
|
||||
query.setFolders([PlacesUtils.bookmarks.tagsFolder], 1);
|
||||
var result = PlacesUtils.history.executeQuery(query, options);
|
||||
var tagRoot = result.root;
|
||||
tagRoot.containerOpen = true;
|
||||
do_check_eq(tagRoot.childCount, 1);
|
||||
var tagNode = tagRoot.getChild(0)
|
||||
.QueryInterface(Ci.nsINavHistoryContainerResultNode);
|
||||
this._tagItemId = tagNode.itemId;
|
||||
tagRoot.containerOpen = false;
|
||||
|
||||
// add a separator and a folder inside tag folder
|
||||
PlacesUtils.bookmarks.insertSeparator(this._tagItemId,
|
||||
PlacesUtils.bookmarks.DEFAULT_INDEX);
|
||||
PlacesUtils.bookmarks.createFolder(this._tagItemId,
|
||||
"test folder",
|
||||
PlacesUtils.bookmarks.DEFAULT_INDEX);
|
||||
|
||||
// add a separator and a folder inside tag root
|
||||
PlacesUtils.bookmarks.insertSeparator(PlacesUtils.bookmarks.tagsFolder,
|
||||
PlacesUtils.bookmarks.DEFAULT_INDEX);
|
||||
PlacesUtils.bookmarks.createFolder(PlacesUtils.bookmarks.tagsFolder,
|
||||
"test tags root folder",
|
||||
PlacesUtils.bookmarks.DEFAULT_INDEX);
|
||||
},
|
||||
|
||||
clean: function () {
|
||||
PlacesUtils.tagging.untagURI(PlacesUtils._uri(this._itemUrl), [this._tag]);
|
||||
PlacesUtils.bookmarks.removeItem(this._itemId);
|
||||
},
|
||||
|
||||
validate: function () {
|
||||
var query = PlacesUtils.history.getNewQuery();
|
||||
query.setFolders([PlacesUtils.bookmarks.toolbarFolder], 1);
|
||||
var options = PlacesUtils.history.getNewQueryOptions();
|
||||
var result = PlacesUtils.history.executeQuery(query, options);
|
||||
|
||||
var toolbar = result.root;
|
||||
toolbar.containerOpen = true;
|
||||
|
||||
// test for our bookmark
|
||||
do_check_eq(toolbar.childCount, 1);
|
||||
for (var i = 0; i < toolbar.childCount; i++) {
|
||||
var folderNode = toolbar.getChild(0);
|
||||
do_check_eq(folderNode.type, folderNode.RESULT_TYPE_URI);
|
||||
do_check_eq(folderNode.title, this._itemTitle);
|
||||
}
|
||||
toolbar.containerOpen = false;
|
||||
|
||||
// test for our tag
|
||||
var tags = PlacesUtils.tagging.getTagsForURI(PlacesUtils._uri(this._itemUrl));
|
||||
do_check_eq(tags.length, 1);
|
||||
do_check_eq(tags[0], this._tag);
|
||||
}
|
||||
}
|
||||
tests.push(invalidTagChildTest);
|
||||
|
||||
function run_test() {
|
||||
run_next_test()
|
||||
}
|
||||
|
||||
add_task(function* () {
|
||||
let jsonFile = OS.Path.join(OS.Constants.Path.profileDir, "bookmarks.json");
|
||||
|
||||
// populate db
|
||||
tests.forEach(function(aTest) {
|
||||
aTest.populate();
|
||||
// sanity
|
||||
aTest.validate();
|
||||
});
|
||||
|
||||
yield BookmarkJSONUtils.exportToFile(jsonFile);
|
||||
|
||||
// clean
|
||||
tests.forEach(function(aTest) {
|
||||
aTest.clean();
|
||||
});
|
||||
|
||||
// restore json file
|
||||
yield BookmarkJSONUtils.importFromFile(jsonFile, true);
|
||||
|
||||
// validate
|
||||
tests.forEach(function(aTest) {
|
||||
aTest.validate();
|
||||
});
|
||||
|
||||
// clean up
|
||||
yield OS.File.remove(jsonFile);
|
||||
});
|
||||
|
|
@ -0,0 +1,124 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim:set ts=2 sw=2 sts=2 et: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
// Since PlacesBackups.getbackupFiles() is a lazy getter, these tests must
|
||||
// run in the given order, to avoid making it out-of-sync.
|
||||
|
||||
add_task(function* check_max_backups_is_respected() {
|
||||
// Get bookmarkBackups directory
|
||||
let backupFolder = yield PlacesBackups.getBackupFolder();
|
||||
|
||||
// Create 2 json dummy backups in the past.
|
||||
let oldJsonPath = OS.Path.join(backupFolder, "bookmarks-2008-01-01.json");
|
||||
let oldJsonFile = yield OS.File.open(oldJsonPath, { truncate: true });
|
||||
oldJsonFile.close();
|
||||
do_check_true(yield OS.File.exists(oldJsonPath));
|
||||
|
||||
let jsonPath = OS.Path.join(backupFolder, "bookmarks-2008-01-31.json");
|
||||
let jsonFile = yield OS.File.open(jsonPath, { truncate: true });
|
||||
jsonFile.close();
|
||||
do_check_true(yield OS.File.exists(jsonPath));
|
||||
|
||||
// Export bookmarks to JSON.
|
||||
// Allow 2 backups, the older one should be removed.
|
||||
yield PlacesBackups.create(2);
|
||||
|
||||
let count = 0;
|
||||
let lastBackupPath = null;
|
||||
let iterator = new OS.File.DirectoryIterator(backupFolder);
|
||||
try {
|
||||
yield iterator.forEach(aEntry => {
|
||||
count++;
|
||||
if (PlacesBackups.filenamesRegex.test(aEntry.name))
|
||||
lastBackupPath = aEntry.path;
|
||||
});
|
||||
} finally {
|
||||
iterator.close();
|
||||
}
|
||||
|
||||
do_check_eq(count, 2);
|
||||
do_check_neq(lastBackupPath, null);
|
||||
do_check_false(yield OS.File.exists(oldJsonPath));
|
||||
do_check_true(yield OS.File.exists(jsonPath));
|
||||
});
|
||||
|
||||
add_task(function* check_max_backups_greater_than_backups() {
|
||||
// Get bookmarkBackups directory
|
||||
let backupFolder = yield PlacesBackups.getBackupFolder();
|
||||
|
||||
// Export bookmarks to JSON.
|
||||
// Allow 3 backups, none should be removed.
|
||||
yield PlacesBackups.create(3);
|
||||
|
||||
let count = 0;
|
||||
let lastBackupPath = null;
|
||||
let iterator = new OS.File.DirectoryIterator(backupFolder);
|
||||
try {
|
||||
yield iterator.forEach(aEntry => {
|
||||
count++;
|
||||
if (PlacesBackups.filenamesRegex.test(aEntry.name))
|
||||
lastBackupPath = aEntry.path;
|
||||
});
|
||||
} finally {
|
||||
iterator.close();
|
||||
}
|
||||
do_check_eq(count, 2);
|
||||
do_check_neq(lastBackupPath, null);
|
||||
});
|
||||
|
||||
add_task(function* check_max_backups_null() {
|
||||
// Get bookmarkBackups directory
|
||||
let backupFolder = yield PlacesBackups.getBackupFolder();
|
||||
|
||||
// Export bookmarks to JSON.
|
||||
// Allow infinite backups, none should be removed, a new one is not created
|
||||
// since one for today already exists.
|
||||
yield PlacesBackups.create(null);
|
||||
|
||||
let count = 0;
|
||||
let lastBackupPath = null;
|
||||
let iterator = new OS.File.DirectoryIterator(backupFolder);
|
||||
try {
|
||||
yield iterator.forEach(aEntry => {
|
||||
count++;
|
||||
if (PlacesBackups.filenamesRegex.test(aEntry.name))
|
||||
lastBackupPath = aEntry.path;
|
||||
});
|
||||
} finally {
|
||||
iterator.close();
|
||||
}
|
||||
do_check_eq(count, 2);
|
||||
do_check_neq(lastBackupPath, null);
|
||||
});
|
||||
|
||||
add_task(function* check_max_backups_undefined() {
|
||||
// Get bookmarkBackups directory
|
||||
let backupFolder = yield PlacesBackups.getBackupFolder();
|
||||
|
||||
// Export bookmarks to JSON.
|
||||
// Allow infinite backups, none should be removed, a new one is not created
|
||||
// since one for today already exists.
|
||||
yield PlacesBackups.create();
|
||||
|
||||
let count = 0;
|
||||
let lastBackupPath = null;
|
||||
let iterator = new OS.File.DirectoryIterator(backupFolder);
|
||||
try {
|
||||
yield iterator.forEach(aEntry => {
|
||||
count++;
|
||||
if (PlacesBackups.filenamesRegex.test(aEntry.name))
|
||||
lastBackupPath = aEntry.path;
|
||||
});
|
||||
} finally {
|
||||
iterator.close();
|
||||
}
|
||||
do_check_eq(count, 2);
|
||||
do_check_neq(lastBackupPath, null);
|
||||
});
|
||||
|
||||
function run_test() {
|
||||
run_next_test();
|
||||
}
|
||||
|
|
@ -0,0 +1,56 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim:set ts=2 sw=2 sts=2 et: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
function run_test() {
|
||||
do_test_pending();
|
||||
|
||||
Task.spawn(function*() {
|
||||
let backupFolder = yield PlacesBackups.getBackupFolder();
|
||||
let bookmarksBackupDir = new FileUtils.File(backupFolder);
|
||||
// Remove all files from backups folder.
|
||||
let files = bookmarksBackupDir.directoryEntries;
|
||||
while (files.hasMoreElements()) {
|
||||
let entry = files.getNext().QueryInterface(Ci.nsIFile);
|
||||
entry.remove(false);
|
||||
}
|
||||
|
||||
// Create a json dummy backup in the future.
|
||||
let dateObj = new Date();
|
||||
dateObj.setYear(dateObj.getFullYear() + 1);
|
||||
let name = PlacesBackups.getFilenameForDate(dateObj);
|
||||
do_check_eq(name, "bookmarks-" + PlacesBackups.toISODateString(dateObj) + ".json");
|
||||
files = bookmarksBackupDir.directoryEntries;
|
||||
while (files.hasMoreElements()) {
|
||||
let entry = files.getNext().QueryInterface(Ci.nsIFile);
|
||||
if (PlacesBackups.filenamesRegex.test(entry.leafName))
|
||||
entry.remove(false);
|
||||
}
|
||||
|
||||
let futureBackupFile = bookmarksBackupDir.clone();
|
||||
futureBackupFile.append(name);
|
||||
futureBackupFile.create(Ci.nsILocalFile.NORMAL_FILE_TYPE, 0o600);
|
||||
do_check_true(futureBackupFile.exists());
|
||||
|
||||
do_check_eq((yield PlacesBackups.getBackupFiles()).length, 0);
|
||||
|
||||
yield PlacesBackups.create();
|
||||
// Check that a backup for today has been created.
|
||||
do_check_eq((yield PlacesBackups.getBackupFiles()).length, 1);
|
||||
let mostRecentBackupFile = yield PlacesBackups.getMostRecentBackup();
|
||||
do_check_neq(mostRecentBackupFile, null);
|
||||
do_check_true(PlacesBackups.filenamesRegex.test(OS.Path.basename(mostRecentBackupFile)));
|
||||
|
||||
// Check that future backup has been removed.
|
||||
do_check_false(futureBackupFile.exists());
|
||||
|
||||
// Cleanup.
|
||||
mostRecentBackupFile = new FileUtils.File(mostRecentBackupFile);
|
||||
mostRecentBackupFile.remove(false);
|
||||
do_check_false(mostRecentBackupFile.exists());
|
||||
|
||||
do_test_finished()
|
||||
});
|
||||
}
|
||||
56
toolkit/components/places/tests/bookmarks/test_675416.js
Normal file
56
toolkit/components/places/tests/bookmarks/test_675416.js
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
function run_test() {
|
||||
/**
|
||||
* Requests information to the service, so that bookmark's data is cached.
|
||||
* @param aItemId
|
||||
* Id of the bookmark to be cached.
|
||||
*/
|
||||
function forceBookmarkCaching(aItemId) {
|
||||
PlacesUtils.bookmarks.getFolderIdForItem(aItemId);
|
||||
}
|
||||
|
||||
let observer = {
|
||||
onBeginUpdateBatch: () => forceBookmarkCaching(itemId1),
|
||||
onEndUpdateBatch: () => forceBookmarkCaching(itemId1),
|
||||
onItemAdded: forceBookmarkCaching,
|
||||
onItemChanged: forceBookmarkCaching,
|
||||
onItemMoved: forceBookmarkCaching,
|
||||
onItemRemoved: function(id) {
|
||||
try {
|
||||
forceBookmarkCaching(id);
|
||||
do_throw("trying to fetch a removed bookmark should throw");
|
||||
} catch (ex) {}
|
||||
},
|
||||
onItemVisited: forceBookmarkCaching,
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsINavBookmarkObserver])
|
||||
};
|
||||
PlacesUtils.bookmarks.addObserver(observer, false);
|
||||
|
||||
let folderId1 = PlacesUtils.bookmarks
|
||||
.createFolder(PlacesUtils.bookmarksMenuFolderId,
|
||||
"Bookmarks",
|
||||
PlacesUtils.bookmarks.DEFAULT_INDEX);
|
||||
let itemId1 = PlacesUtils.bookmarks
|
||||
.insertBookmark(folderId1,
|
||||
NetUtil.newURI("http:/www.wired.com/wiredscience"),
|
||||
PlacesUtils.bookmarks.DEFAULT_INDEX,
|
||||
"Wired Science");
|
||||
|
||||
PlacesUtils.bookmarks.removeItem(folderId1);
|
||||
|
||||
let folderId2 = PlacesUtils.bookmarks
|
||||
.createFolder(PlacesUtils.bookmarksMenuFolderId,
|
||||
"Science",
|
||||
PlacesUtils.bookmarks.DEFAULT_INDEX);
|
||||
let folderId3 = PlacesUtils.bookmarks
|
||||
.createFolder(folderId2,
|
||||
"Blogs",
|
||||
PlacesUtils.bookmarks.DEFAULT_INDEX);
|
||||
// Check title is correctly reported.
|
||||
do_check_eq(PlacesUtils.bookmarks.getItemTitle(folderId3), "Blogs");
|
||||
do_check_eq(PlacesUtils.bookmarks.getItemTitle(folderId2), "Science");
|
||||
|
||||
PlacesUtils.bookmarks.removeObserver(observer, false);
|
||||
}
|
||||
56
toolkit/components/places/tests/bookmarks/test_711914.js
Normal file
56
toolkit/components/places/tests/bookmarks/test_711914.js
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
function run_test() {
|
||||
/**
|
||||
* Requests information to the service, so that bookmark's data is cached.
|
||||
* @param aItemId
|
||||
* Id of the bookmark to be cached.
|
||||
*/
|
||||
function forceBookmarkCaching(aItemId) {
|
||||
let parent = PlacesUtils.bookmarks.getFolderIdForItem(aItemId);
|
||||
PlacesUtils.bookmarks.getFolderIdForItem(parent);
|
||||
}
|
||||
|
||||
let observer = {
|
||||
onBeginUpdateBatch: () => forceBookmarkCaching(itemId1),
|
||||
onEndUpdateBatch: () => forceBookmarkCaching(itemId1),
|
||||
onItemAdded: forceBookmarkCaching,
|
||||
onItemChanged: forceBookmarkCaching,
|
||||
onItemMoved: forceBookmarkCaching,
|
||||
onItemRemoved: function (id) {
|
||||
try {
|
||||
forceBookmarkCaching(id);
|
||||
do_throw("trying to fetch a removed bookmark should throw");
|
||||
} catch (ex) {}
|
||||
},
|
||||
onItemVisited: forceBookmarkCaching,
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsINavBookmarkObserver])
|
||||
};
|
||||
PlacesUtils.bookmarks.addObserver(observer, false);
|
||||
|
||||
let folder1 = PlacesUtils.bookmarks
|
||||
.createFolder(PlacesUtils.bookmarksMenuFolderId,
|
||||
"Folder1",
|
||||
PlacesUtils.bookmarks.DEFAULT_INDEX);
|
||||
let folder2 = PlacesUtils.bookmarks
|
||||
.createFolder(folder1,
|
||||
"Folder2",
|
||||
PlacesUtils.bookmarks.DEFAULT_INDEX);
|
||||
PlacesUtils.bookmarks.insertBookmark(folder2,
|
||||
NetUtil.newURI("http://mozilla.org/"),
|
||||
PlacesUtils.bookmarks.DEFAULT_INDEX,
|
||||
"Mozilla");
|
||||
|
||||
PlacesUtils.bookmarks.removeFolderChildren(folder1);
|
||||
|
||||
// Check title is correctly reported.
|
||||
do_check_eq(PlacesUtils.bookmarks.getItemTitle(folder1), "Folder1");
|
||||
try {
|
||||
PlacesUtils.bookmarks.getItemTitle(folder2);
|
||||
do_throw("trying to fetch a removed bookmark should throw");
|
||||
} catch (ex) {}
|
||||
|
||||
PlacesUtils.bookmarks.removeObserver(observer, false);
|
||||
}
|
||||
|
|
@ -0,0 +1,59 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/**
|
||||
* Checks that automatically created bookmark backups are discarded if they are
|
||||
* duplicate of an existing ones.
|
||||
*/
|
||||
function run_test() {
|
||||
run_next_test();
|
||||
}
|
||||
|
||||
add_task(function*() {
|
||||
// Create a backup for yesterday in the backups folder.
|
||||
let backupFolder = yield PlacesBackups.getBackupFolder();
|
||||
let dateObj = new Date();
|
||||
dateObj.setDate(dateObj.getDate() - 1);
|
||||
let oldBackupName = PlacesBackups.getFilenameForDate(dateObj);
|
||||
let oldBackup = OS.Path.join(backupFolder, oldBackupName);
|
||||
let {count: count, hash: hash} = yield BookmarkJSONUtils.exportToFile(oldBackup);
|
||||
do_check_true(count > 0);
|
||||
do_check_eq(hash.length, 24);
|
||||
oldBackupName = oldBackupName.replace(/\.json/, "_" + count + "_" + hash + ".json");
|
||||
yield OS.File.move(oldBackup, OS.Path.join(backupFolder, oldBackupName));
|
||||
|
||||
// Create a backup.
|
||||
// This should just rename the existing backup, so in the end there should be
|
||||
// only one backup with today's date.
|
||||
yield PlacesBackups.create();
|
||||
|
||||
// Get the hash of the generated backup
|
||||
let backupFiles = yield PlacesBackups.getBackupFiles();
|
||||
do_check_eq(backupFiles.length, 1);
|
||||
|
||||
let matches = OS.Path.basename(backupFiles[0]).match(PlacesBackups.filenamesRegex);
|
||||
do_check_eq(matches[1], PlacesBackups.toISODateString(new Date()));
|
||||
do_check_eq(matches[2], count);
|
||||
do_check_eq(matches[3], hash);
|
||||
|
||||
// Add a bookmark and create another backup.
|
||||
let bookmarkId = PlacesUtils.bookmarks.insertBookmark(PlacesUtils.bookmarks.bookmarksMenuFolder,
|
||||
uri("http://foo.com"),
|
||||
PlacesUtils.bookmarks.DEFAULT_INDEX,
|
||||
"foo");
|
||||
// We must enforce a backup since one for today already exists. The forced
|
||||
// backup will replace the existing one.
|
||||
yield PlacesBackups.create(undefined, true);
|
||||
do_check_eq(backupFiles.length, 1);
|
||||
recentBackup = yield PlacesBackups.getMostRecentBackup();
|
||||
do_check_neq(recentBackup, OS.Path.join(backupFolder, oldBackupName));
|
||||
matches = OS.Path.basename(recentBackup).match(PlacesBackups.filenamesRegex);
|
||||
do_check_eq(matches[1], PlacesBackups.toISODateString(new Date()));
|
||||
do_check_eq(matches[2], count + 1);
|
||||
do_check_neq(matches[3], hash);
|
||||
|
||||
// Clean up
|
||||
PlacesUtils.bookmarks.removeItem(bookmarkId);
|
||||
yield PlacesBackups.create(0);
|
||||
});
|
||||
|
|
@ -0,0 +1,57 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim:set ts=2 sw=2 sts=2 et: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
function run_test() {
|
||||
run_next_test();
|
||||
}
|
||||
|
||||
add_task(function* compress_bookmark_backups_test() {
|
||||
// Check for jsonlz4 extension
|
||||
let todayFilename = PlacesBackups.getFilenameForDate(new Date(2014, 4, 15), true);
|
||||
do_check_eq(todayFilename, "bookmarks-2014-05-15.jsonlz4");
|
||||
|
||||
yield PlacesBackups.create();
|
||||
|
||||
// Check that a backup for today has been created and the regex works fine for lz4.
|
||||
do_check_eq((yield PlacesBackups.getBackupFiles()).length, 1);
|
||||
let mostRecentBackupFile = yield PlacesBackups.getMostRecentBackup();
|
||||
do_check_neq(mostRecentBackupFile, null);
|
||||
do_check_true(PlacesBackups.filenamesRegex.test(OS.Path.basename(mostRecentBackupFile)));
|
||||
|
||||
// The most recent backup file has to be removed since saveBookmarksToJSONFile
|
||||
// will otherwise over-write the current backup, since it will be made on the
|
||||
// same date
|
||||
yield OS.File.remove(mostRecentBackupFile);
|
||||
do_check_false((yield OS.File.exists(mostRecentBackupFile)));
|
||||
|
||||
// Check that, if the user created a custom backup out of the default
|
||||
// backups folder, it gets copied (compressed) into it.
|
||||
let jsonFile = OS.Path.join(OS.Constants.Path.profileDir, "bookmarks.json");
|
||||
yield PlacesBackups.saveBookmarksToJSONFile(jsonFile);
|
||||
do_check_eq((yield PlacesBackups.getBackupFiles()).length, 1);
|
||||
|
||||
// Check if import works from lz4 compressed json
|
||||
let uri = NetUtil.newURI("http://www.mozilla.org/en-US/");
|
||||
let bm = PlacesUtils.bookmarks.insertBookmark(PlacesUtils.unfiledBookmarksFolderId,
|
||||
uri,
|
||||
PlacesUtils.bookmarks.DEFAULT_INDEX,
|
||||
"bookmark");
|
||||
|
||||
// Force create a compressed backup, Remove the bookmark, the restore the backup
|
||||
yield PlacesBackups.create(undefined, true);
|
||||
let recentBackup = yield PlacesBackups.getMostRecentBackup();
|
||||
PlacesUtils.bookmarks.removeItem(bm);
|
||||
yield BookmarkJSONUtils.importFromFile(recentBackup, true);
|
||||
let root = PlacesUtils.getFolderContents(PlacesUtils.unfiledBookmarksFolderId).root;
|
||||
let node = root.getChild(0);
|
||||
do_check_eq(node.uri, uri.spec);
|
||||
|
||||
root.containerOpen = false;
|
||||
PlacesUtils.bookmarks.removeFolderChildren(PlacesUtils.unfiledBookmarksFolderId);
|
||||
|
||||
// Cleanup.
|
||||
yield OS.File.remove(jsonFile);
|
||||
});
|
||||
|
|
@ -0,0 +1,57 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/**
|
||||
* To confirm that metadata i.e. bookmark count is set and retrieved for
|
||||
* automatic backups.
|
||||
*/
|
||||
function run_test() {
|
||||
run_next_test();
|
||||
}
|
||||
|
||||
add_task(function* test_saveBookmarksToJSONFile_and_create()
|
||||
{
|
||||
// Add a bookmark
|
||||
let uri = NetUtil.newURI("http://getfirefox.com/");
|
||||
let bookmarkId =
|
||||
PlacesUtils.bookmarks.insertBookmark(
|
||||
PlacesUtils.unfiledBookmarksFolderId, uri,
|
||||
PlacesUtils.bookmarks.DEFAULT_INDEX, "Get Firefox!");
|
||||
|
||||
// Test saveBookmarksToJSONFile()
|
||||
let backupFile = FileUtils.getFile("TmpD", ["bookmarks.json"]);
|
||||
backupFile.create(Ci.nsILocalFile.NORMAL_FILE_TYPE, parseInt("0600", 8));
|
||||
|
||||
let nodeCount = yield PlacesBackups.saveBookmarksToJSONFile(backupFile, true);
|
||||
do_check_true(nodeCount > 0);
|
||||
do_check_true(backupFile.exists());
|
||||
do_check_eq(backupFile.leafName, "bookmarks.json");
|
||||
|
||||
// Ensure the backup would be copied to our backups folder when the original
|
||||
// backup is saved somewhere else.
|
||||
let recentBackup = yield PlacesBackups.getMostRecentBackup();
|
||||
let matches = OS.Path.basename(recentBackup).match(PlacesBackups.filenamesRegex);
|
||||
do_check_eq(matches[2], nodeCount);
|
||||
do_check_eq(matches[3].length, 24);
|
||||
|
||||
// Clear all backups in our backups folder.
|
||||
yield PlacesBackups.create(0);
|
||||
do_check_eq((yield PlacesBackups.getBackupFiles()).length, 0);
|
||||
|
||||
// Test create() which saves bookmarks with metadata on the filename.
|
||||
yield PlacesBackups.create();
|
||||
do_check_eq((yield PlacesBackups.getBackupFiles()).length, 1);
|
||||
|
||||
mostRecentBackupFile = yield PlacesBackups.getMostRecentBackup();
|
||||
do_check_neq(mostRecentBackupFile, null);
|
||||
matches = OS.Path.basename(recentBackup).match(PlacesBackups.filenamesRegex);
|
||||
do_check_eq(matches[2], nodeCount);
|
||||
do_check_eq(matches[3].length, 24);
|
||||
|
||||
// Cleanup
|
||||
backupFile.remove(false);
|
||||
yield PlacesBackups.create(0);
|
||||
PlacesUtils.bookmarks.removeItem(bookmarkId);
|
||||
});
|
||||
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/**
|
||||
* Checks that backups properly include all of the bookmarks if the hierarchy
|
||||
* in the database is unordered so that a hierarchy is defined before its
|
||||
* ancestor in the bookmarks table.
|
||||
*/
|
||||
function run_test() {
|
||||
run_next_test();
|
||||
}
|
||||
|
||||
add_task(function*() {
|
||||
let bm = PlacesUtils.bookmarks.insertBookmark(PlacesUtils.unfiledBookmarksFolderId,
|
||||
NetUtil.newURI("http://mozilla.org/"),
|
||||
PlacesUtils.bookmarks.DEFAULT_INDEX,
|
||||
"bookmark");
|
||||
let f2 = PlacesUtils.bookmarks.createFolder(PlacesUtils.unfiledBookmarksFolderId, "f2",
|
||||
PlacesUtils.bookmarks.DEFAULT_INDEX);
|
||||
PlacesUtils.bookmarks.moveItem(bm, f2, PlacesUtils.bookmarks.DEFAULT_INDEX);
|
||||
let f1 = PlacesUtils.bookmarks.createFolder(PlacesUtils.unfiledBookmarksFolderId, "f1",
|
||||
PlacesUtils.bookmarks.DEFAULT_INDEX);
|
||||
PlacesUtils.bookmarks.moveItem(f2, f1, PlacesUtils.bookmarks.DEFAULT_INDEX);
|
||||
|
||||
// Create a backup.
|
||||
yield PlacesBackups.create();
|
||||
|
||||
// Remove the bookmarks, then restore the backup.
|
||||
PlacesUtils.bookmarks.removeItem(f1);
|
||||
yield BookmarkJSONUtils.importFromFile((yield PlacesBackups.getMostRecentBackup()), true);
|
||||
|
||||
do_print("Checking first level");
|
||||
let root = PlacesUtils.getFolderContents(PlacesUtils.unfiledBookmarksFolderId).root;
|
||||
let level1 = root.getChild(0);
|
||||
do_check_eq(level1.title, "f1");
|
||||
do_print("Checking second level");
|
||||
PlacesUtils.asContainer(level1).containerOpen = true
|
||||
let level2 = level1.getChild(0);
|
||||
do_check_eq(level2.title, "f2");
|
||||
do_print("Checking bookmark");
|
||||
PlacesUtils.asContainer(level2).containerOpen = true
|
||||
let bookmark = level2.getChild(0);
|
||||
do_check_eq(bookmark.title, "bookmark");
|
||||
level2.containerOpen = false;
|
||||
level1.containerOpen = false;
|
||||
root.containerOpen = false;
|
||||
});
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/**
|
||||
* Checks that we don't encodeURI twice when creating bookmarks.html.
|
||||
*/
|
||||
|
||||
function run_test() {
|
||||
run_next_test();
|
||||
}
|
||||
|
||||
add_task(function* () {
|
||||
let uri = NetUtil.newURI("http://bt.ktxp.com/search.php?keyword=%E5%A6%84%E6%83%B3%E5%AD%A6%E7%94%9F%E4%BC%9A");
|
||||
let bm = PlacesUtils.bookmarks.insertBookmark(PlacesUtils.unfiledBookmarksFolderId,
|
||||
uri,
|
||||
PlacesUtils.bookmarks.DEFAULT_INDEX,
|
||||
"bookmark");
|
||||
|
||||
let file = OS.Path.join(OS.Constants.Path.profileDir, "bookmarks.exported.997030.html");
|
||||
if ((yield OS.File.exists(file))) {
|
||||
yield OS.File.remove(file);
|
||||
}
|
||||
yield BookmarkHTMLUtils.exportToFile(file);
|
||||
|
||||
// Remove the bookmarks, then restore the backup.
|
||||
PlacesUtils.bookmarks.removeItem(bm);
|
||||
yield BookmarkHTMLUtils.importFromFile(file, true);
|
||||
|
||||
do_print("Checking first level");
|
||||
let root = PlacesUtils.getFolderContents(PlacesUtils.unfiledBookmarksFolderId).root;
|
||||
let node = root.getChild(0);
|
||||
do_check_eq(node.uri, uri.spec);
|
||||
|
||||
root.containerOpen = false;
|
||||
PlacesUtils.bookmarks.removeFolderChildren(PlacesUtils.unfiledBookmarksFolderId);
|
||||
});
|
||||
|
|
@ -0,0 +1,177 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/* This test checks that bookmarks service is correctly forwarding async
|
||||
* events like visit or favicon additions. */
|
||||
|
||||
const NOW = Date.now() * 1000;
|
||||
|
||||
var observer = {
|
||||
bookmarks: [],
|
||||
observedBookmarks: 0,
|
||||
observedVisitId: 0,
|
||||
deferred: null,
|
||||
|
||||
/**
|
||||
* Returns a promise that is resolved when the observer determines that the
|
||||
* test can continue. This is required rather than calling run_next_test
|
||||
* directly in the observer because there are cases where we must wait for
|
||||
* other asynchronous events to be completed in addition to this.
|
||||
*/
|
||||
setupCompletionPromise: function ()
|
||||
{
|
||||
this.observedBookmarks = 0;
|
||||
this.deferred = Promise.defer();
|
||||
return this.deferred.promise;
|
||||
},
|
||||
|
||||
onBeginUpdateBatch: function () {},
|
||||
onEndUpdateBatch: function () {},
|
||||
onItemAdded: function () {},
|
||||
onItemRemoved: function () {},
|
||||
onItemMoved: function () {},
|
||||
onItemChanged: function(aItemId, aProperty, aIsAnnotation, aNewValue,
|
||||
aLastModified, aItemType)
|
||||
{
|
||||
do_print("Check that we got the correct change information.");
|
||||
do_check_neq(this.bookmarks.indexOf(aItemId), -1);
|
||||
if (aProperty == "favicon") {
|
||||
do_check_false(aIsAnnotation);
|
||||
do_check_eq(aNewValue, SMALLPNG_DATA_URI.spec);
|
||||
do_check_eq(aLastModified, 0);
|
||||
do_check_eq(aItemType, PlacesUtils.bookmarks.TYPE_BOOKMARK);
|
||||
}
|
||||
else if (aProperty == "cleartime") {
|
||||
do_check_false(aIsAnnotation);
|
||||
do_check_eq(aNewValue, "");
|
||||
do_check_eq(aLastModified, 0);
|
||||
do_check_eq(aItemType, PlacesUtils.bookmarks.TYPE_BOOKMARK);
|
||||
}
|
||||
else {
|
||||
do_throw("Unexpected property change " + aProperty);
|
||||
}
|
||||
|
||||
if (++this.observedBookmarks == this.bookmarks.length) {
|
||||
this.deferred.resolve();
|
||||
}
|
||||
},
|
||||
onItemVisited: function(aItemId, aVisitId, aTime)
|
||||
{
|
||||
do_print("Check that we got the correct visit information.");
|
||||
do_check_neq(this.bookmarks.indexOf(aItemId), -1);
|
||||
this.observedVisitId = aVisitId;
|
||||
do_check_eq(aTime, NOW);
|
||||
if (++this.observedBookmarks == this.bookmarks.length) {
|
||||
this.deferred.resolve();
|
||||
}
|
||||
},
|
||||
|
||||
QueryInterface: XPCOMUtils.generateQI([
|
||||
Ci.nsINavBookmarkObserver,
|
||||
])
|
||||
};
|
||||
PlacesUtils.bookmarks.addObserver(observer, false);
|
||||
|
||||
add_task(function* test_add_visit()
|
||||
{
|
||||
let observerPromise = observer.setupCompletionPromise();
|
||||
|
||||
// Add a visit to the bookmark and wait for the observer.
|
||||
let visitId;
|
||||
let deferUpdatePlaces = Promise.defer();
|
||||
PlacesUtils.asyncHistory.updatePlaces({
|
||||
uri: NetUtil.newURI("http://book.ma.rk/"),
|
||||
visits: [{ transitionType: TRANSITION_TYPED, visitDate: NOW }]
|
||||
}, {
|
||||
handleError: function TAV_handleError() {
|
||||
deferUpdatePlaces.reject(new Error("Unexpected error in adding visit."));
|
||||
},
|
||||
handleResult: function (aPlaceInfo) {
|
||||
visitId = aPlaceInfo.visits[0].visitId;
|
||||
},
|
||||
handleCompletion: function TAV_handleCompletion() {
|
||||
deferUpdatePlaces.resolve();
|
||||
}
|
||||
});
|
||||
|
||||
// Wait for both the observer and the asynchronous update, in any order.
|
||||
yield deferUpdatePlaces.promise;
|
||||
yield observerPromise;
|
||||
|
||||
// Check that both asynchronous results are consistent.
|
||||
do_check_eq(observer.observedVisitId, visitId);
|
||||
});
|
||||
|
||||
add_task(function* test_add_icon()
|
||||
{
|
||||
let observerPromise = observer.setupCompletionPromise();
|
||||
PlacesUtils.favicons.setAndFetchFaviconForPage(NetUtil.newURI("http://book.ma.rk/"),
|
||||
SMALLPNG_DATA_URI, true,
|
||||
PlacesUtils.favicons.FAVICON_LOAD_NON_PRIVATE,
|
||||
null,
|
||||
Services.scriptSecurityManager.getSystemPrincipal());
|
||||
yield observerPromise;
|
||||
});
|
||||
|
||||
add_task(function* test_remove_page()
|
||||
{
|
||||
let observerPromise = observer.setupCompletionPromise();
|
||||
PlacesUtils.history.removePage(NetUtil.newURI("http://book.ma.rk/"));
|
||||
yield observerPromise;
|
||||
});
|
||||
|
||||
add_task(function cleanup()
|
||||
{
|
||||
PlacesUtils.bookmarks.removeObserver(observer, false);
|
||||
});
|
||||
|
||||
add_task(function* shutdown()
|
||||
{
|
||||
// Check that async observers don't try to create async statements after
|
||||
// shutdown. That would cause assertions, since the async thread is gone
|
||||
// already. Note that in such a case the notifications are not fired, so we
|
||||
// cannot test for them.
|
||||
// Put an history notification that triggers AsyncGetBookmarksForURI between
|
||||
// asyncClose() and the actual connection closing. Enqueuing a main-thread
|
||||
// event just after places-will-close-connection should ensure it runs before
|
||||
// places-connection-closed.
|
||||
// Notice this code is not using helpers cause it depends on a very specific
|
||||
// order, a change in the helpers code could make this test useless.
|
||||
let deferred = Promise.defer();
|
||||
|
||||
Services.obs.addObserver(function onNotification() {
|
||||
Services.obs.removeObserver(onNotification, "places-will-close-connection");
|
||||
do_check_true(true, "Observed fake places shutdown");
|
||||
|
||||
Services.tm.mainThread.dispatch(() => {
|
||||
// WARNING: this is very bad, never use out of testing code.
|
||||
PlacesUtils.bookmarks.QueryInterface(Ci.nsINavHistoryObserver)
|
||||
.onPageChanged(NetUtil.newURI("http://book.ma.rk/"),
|
||||
Ci.nsINavHistoryObserver.ATTRIBUTE_FAVICON,
|
||||
"test", "test");
|
||||
deferred.resolve(promiseTopicObserved("places-connection-closed"));
|
||||
}, Ci.nsIThread.DISPATCH_NORMAL);
|
||||
}, "places-will-close-connection", false);
|
||||
shutdownPlaces();
|
||||
|
||||
yield deferred.promise;
|
||||
});
|
||||
|
||||
function run_test()
|
||||
{
|
||||
// Add multiple bookmarks to the same uri.
|
||||
observer.bookmarks.push(
|
||||
PlacesUtils.bookmarks.insertBookmark(PlacesUtils.unfiledBookmarksFolderId,
|
||||
NetUtil.newURI("http://book.ma.rk/"),
|
||||
PlacesUtils.bookmarks.DEFAULT_INDEX,
|
||||
"Bookmark")
|
||||
);
|
||||
observer.bookmarks.push(
|
||||
PlacesUtils.bookmarks.insertBookmark(PlacesUtils.toolbarFolderId,
|
||||
NetUtil.newURI("http://book.ma.rk/"),
|
||||
PlacesUtils.bookmarks.DEFAULT_INDEX,
|
||||
"Bookmark")
|
||||
);
|
||||
|
||||
run_next_test();
|
||||
}
|
||||
124
toolkit/components/places/tests/bookmarks/test_bmindex.js
Normal file
124
toolkit/components/places/tests/bookmarks/test_bmindex.js
Normal file
|
|
@ -0,0 +1,124 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*-
|
||||
* vim: sw=2 ts=2 et lcs=trail\:.,tab\:>~ :
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
const NUM_BOOKMARKS = 20;
|
||||
const NUM_SEPARATORS = 5;
|
||||
const NUM_FOLDERS = 10;
|
||||
const NUM_ITEMS = NUM_BOOKMARKS + NUM_SEPARATORS + NUM_FOLDERS;
|
||||
const MIN_RAND = -5;
|
||||
const MAX_RAND = 40;
|
||||
|
||||
var bs = Cc["@mozilla.org/browser/nav-bookmarks-service;1"].
|
||||
getService(Ci.nsINavBookmarksService);
|
||||
|
||||
function check_contiguous_indexes(aBookmarks) {
|
||||
var indexes = [];
|
||||
aBookmarks.forEach(function(aBookmarkId) {
|
||||
let bmIndex = bs.getItemIndex(aBookmarkId);
|
||||
dump("Index: " + bmIndex + "\n");
|
||||
dump("Checking duplicates\n");
|
||||
do_check_eq(indexes.indexOf(bmIndex), -1);
|
||||
dump("Checking out of range, found " + aBookmarks.length + " items\n");
|
||||
do_check_true(bmIndex >= 0 && bmIndex < aBookmarks.length);
|
||||
indexes.push(bmIndex);
|
||||
});
|
||||
dump("Checking all valid indexes have been used\n");
|
||||
do_check_eq(indexes.length, aBookmarks.length);
|
||||
}
|
||||
|
||||
// main
|
||||
function run_test() {
|
||||
var bookmarks = [];
|
||||
// Insert bookmarks with random indexes.
|
||||
for (let i = 0; bookmarks.length < NUM_BOOKMARKS; i++) {
|
||||
let randIndex = Math.round(MIN_RAND + (Math.random() * (MAX_RAND - MIN_RAND)));
|
||||
try {
|
||||
let id = bs.insertBookmark(bs.unfiledBookmarksFolder,
|
||||
uri("http://" + i + ".mozilla.org/"),
|
||||
randIndex, "Test bookmark " + i);
|
||||
if (randIndex < -1)
|
||||
do_throw("Creating a bookmark at an invalid index should throw");
|
||||
bookmarks.push(id);
|
||||
}
|
||||
catch (ex) {
|
||||
if (randIndex >= -1)
|
||||
do_throw("Creating a bookmark at a valid index should not throw");
|
||||
}
|
||||
}
|
||||
check_contiguous_indexes(bookmarks);
|
||||
|
||||
// Insert separators with random indexes.
|
||||
for (let i = 0; bookmarks.length < NUM_BOOKMARKS + NUM_SEPARATORS; i++) {
|
||||
let randIndex = Math.round(MIN_RAND + (Math.random() * (MAX_RAND - MIN_RAND)));
|
||||
try {
|
||||
let id = bs.insertSeparator(bs.unfiledBookmarksFolder, randIndex);
|
||||
if (randIndex < -1)
|
||||
do_throw("Creating a separator at an invalid index should throw");
|
||||
bookmarks.push(id);
|
||||
}
|
||||
catch (ex) {
|
||||
if (randIndex >= -1)
|
||||
do_throw("Creating a separator at a valid index should not throw");
|
||||
}
|
||||
}
|
||||
check_contiguous_indexes(bookmarks);
|
||||
|
||||
// Insert folders with random indexes.
|
||||
for (let i = 0; bookmarks.length < NUM_ITEMS; i++) {
|
||||
let randIndex = Math.round(MIN_RAND + (Math.random() * (MAX_RAND - MIN_RAND)));
|
||||
try {
|
||||
let id = bs.createFolder(bs.unfiledBookmarksFolder,
|
||||
"Test folder " + i, randIndex);
|
||||
if (randIndex < -1)
|
||||
do_throw("Creating a folder at an invalid index should throw");
|
||||
bookmarks.push(id);
|
||||
}
|
||||
catch (ex) {
|
||||
if (randIndex >= -1)
|
||||
do_throw("Creating a folder at a valid index should not throw");
|
||||
}
|
||||
}
|
||||
check_contiguous_indexes(bookmarks);
|
||||
|
||||
// Execute some random bookmark delete.
|
||||
for (let i = 0; i < Math.ceil(NUM_ITEMS / 4); i++) {
|
||||
let id = bookmarks.splice(Math.floor(Math.random() * bookmarks.length), 1);
|
||||
dump("Removing item with id " + id + "\n");
|
||||
bs.removeItem(id);
|
||||
}
|
||||
check_contiguous_indexes(bookmarks);
|
||||
|
||||
// Execute some random bookmark move. This will also try to move it to
|
||||
// invalid index values.
|
||||
for (let i = 0; i < Math.ceil(NUM_ITEMS / 4); i++) {
|
||||
let randIndex = Math.floor(Math.random() * bookmarks.length);
|
||||
let id = bookmarks[randIndex];
|
||||
let newIndex = Math.round(MIN_RAND + (Math.random() * (MAX_RAND - MIN_RAND)));
|
||||
dump("Moving item with id " + id + " to index " + newIndex + "\n");
|
||||
try {
|
||||
bs.moveItem(id, bs.unfiledBookmarksFolder, newIndex);
|
||||
if (newIndex < -1)
|
||||
do_throw("Moving an item to a negative index should throw\n");
|
||||
}
|
||||
catch (ex) {
|
||||
if (newIndex >= -1)
|
||||
do_throw("Moving an item to a valid index should not throw\n");
|
||||
}
|
||||
|
||||
}
|
||||
check_contiguous_indexes(bookmarks);
|
||||
|
||||
// Ensure setItemIndex throws if we pass it a negative index.
|
||||
try {
|
||||
bs.setItemIndex(bookmarks[0], -1);
|
||||
do_throw("setItemIndex should throw for a negative index");
|
||||
} catch (ex) {}
|
||||
// Ensure setItemIndex throws if we pass it a bad itemId.
|
||||
try {
|
||||
bs.setItemIndex(0, 5);
|
||||
do_throw("setItemIndex should throw for a bad itemId");
|
||||
} catch (ex) {}
|
||||
}
|
||||
718
toolkit/components/places/tests/bookmarks/test_bookmarks.js
Normal file
718
toolkit/components/places/tests/bookmarks/test_bookmarks.js
Normal file
|
|
@ -0,0 +1,718 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim:set ts=2 sw=2 sts=2 et: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
var bs = PlacesUtils.bookmarks;
|
||||
var hs = PlacesUtils.history;
|
||||
var anno = PlacesUtils.annotations;
|
||||
|
||||
|
||||
var bookmarksObserver = {
|
||||
onBeginUpdateBatch: function() {
|
||||
this._beginUpdateBatch = true;
|
||||
},
|
||||
onEndUpdateBatch: function() {
|
||||
this._endUpdateBatch = true;
|
||||
},
|
||||
onItemAdded: function(id, folder, index, itemType, uri, title, dateAdded,
|
||||
guid) {
|
||||
this._itemAddedId = id;
|
||||
this._itemAddedParent = folder;
|
||||
this._itemAddedIndex = index;
|
||||
this._itemAddedURI = uri;
|
||||
this._itemAddedTitle = title;
|
||||
|
||||
// Ensure that we've created a guid for this item.
|
||||
let stmt = DBConn().createStatement(
|
||||
`SELECT guid
|
||||
FROM moz_bookmarks
|
||||
WHERE id = :item_id`
|
||||
);
|
||||
stmt.params.item_id = id;
|
||||
do_check_true(stmt.executeStep());
|
||||
do_check_false(stmt.getIsNull(0));
|
||||
do_check_valid_places_guid(stmt.row.guid);
|
||||
do_check_eq(stmt.row.guid, guid);
|
||||
stmt.finalize();
|
||||
},
|
||||
onItemRemoved: function(id, folder, index, itemType) {
|
||||
this._itemRemovedId = id;
|
||||
this._itemRemovedFolder = folder;
|
||||
this._itemRemovedIndex = index;
|
||||
},
|
||||
onItemChanged: function(id, property, isAnnotationProperty, value,
|
||||
lastModified, itemType, parentId, guid, parentGuid,
|
||||
oldValue) {
|
||||
this._itemChangedId = id;
|
||||
this._itemChangedProperty = property;
|
||||
this._itemChanged_isAnnotationProperty = isAnnotationProperty;
|
||||
this._itemChangedValue = value;
|
||||
this._itemChangedOldValue = oldValue;
|
||||
},
|
||||
onItemVisited: function(id, visitID, time) {
|
||||
this._itemVisitedId = id;
|
||||
this._itemVisitedVistId = visitID;
|
||||
this._itemVisitedTime = time;
|
||||
},
|
||||
onItemMoved: function(id, oldParent, oldIndex, newParent, newIndex,
|
||||
itemType) {
|
||||
this._itemMovedId = id
|
||||
this._itemMovedOldParent = oldParent;
|
||||
this._itemMovedOldIndex = oldIndex;
|
||||
this._itemMovedNewParent = newParent;
|
||||
this._itemMovedNewIndex = newIndex;
|
||||
},
|
||||
QueryInterface: XPCOMUtils.generateQI([
|
||||
Ci.nsINavBookmarkObserver,
|
||||
])
|
||||
};
|
||||
|
||||
|
||||
// Get bookmarks menu folder id.
|
||||
var root = bs.bookmarksMenuFolder;
|
||||
// Index at which items should begin.
|
||||
var bmStartIndex = 0;
|
||||
|
||||
|
||||
function run_test() {
|
||||
run_next_test();
|
||||
}
|
||||
|
||||
add_task(function* test_bookmarks() {
|
||||
bs.addObserver(bookmarksObserver, false);
|
||||
|
||||
// test special folders
|
||||
do_check_true(bs.placesRoot > 0);
|
||||
do_check_true(bs.bookmarksMenuFolder > 0);
|
||||
do_check_true(bs.tagsFolder > 0);
|
||||
do_check_true(bs.toolbarFolder > 0);
|
||||
do_check_true(bs.unfiledBookmarksFolder > 0);
|
||||
|
||||
// test getFolderIdForItem() with bogus item id will throw
|
||||
try {
|
||||
bs.getFolderIdForItem(0);
|
||||
do_throw("getFolderIdForItem accepted bad input");
|
||||
} catch (ex) {}
|
||||
|
||||
// test getFolderIdForItem() with bogus item id will throw
|
||||
try {
|
||||
bs.getFolderIdForItem(-1);
|
||||
do_throw("getFolderIdForItem accepted bad input");
|
||||
} catch (ex) {}
|
||||
|
||||
// test root parentage
|
||||
do_check_eq(bs.getFolderIdForItem(bs.bookmarksMenuFolder), bs.placesRoot);
|
||||
do_check_eq(bs.getFolderIdForItem(bs.tagsFolder), bs.placesRoot);
|
||||
do_check_eq(bs.getFolderIdForItem(bs.toolbarFolder), bs.placesRoot);
|
||||
do_check_eq(bs.getFolderIdForItem(bs.unfiledBookmarksFolder), bs.placesRoot);
|
||||
|
||||
// create a folder to hold all the tests
|
||||
// this makes the tests more tolerant of changes to default_places.html
|
||||
let testRoot = bs.createFolder(root, "places bookmarks xpcshell tests",
|
||||
bs.DEFAULT_INDEX);
|
||||
do_check_eq(bookmarksObserver._itemAddedId, testRoot);
|
||||
do_check_eq(bookmarksObserver._itemAddedParent, root);
|
||||
do_check_eq(bookmarksObserver._itemAddedIndex, bmStartIndex);
|
||||
do_check_eq(bookmarksObserver._itemAddedURI, null);
|
||||
let testStartIndex = 0;
|
||||
|
||||
// test getItemIndex for folders
|
||||
do_check_eq(bs.getItemIndex(testRoot), bmStartIndex);
|
||||
|
||||
// test getItemType for folders
|
||||
do_check_eq(bs.getItemType(testRoot), bs.TYPE_FOLDER);
|
||||
|
||||
// insert a bookmark.
|
||||
// the time before we insert, in microseconds
|
||||
let beforeInsert = Date.now() * 1000;
|
||||
do_check_true(beforeInsert > 0);
|
||||
|
||||
let newId = bs.insertBookmark(testRoot, uri("http://google.com/"),
|
||||
bs.DEFAULT_INDEX, "");
|
||||
do_check_eq(bookmarksObserver._itemAddedId, newId);
|
||||
do_check_eq(bookmarksObserver._itemAddedParent, testRoot);
|
||||
do_check_eq(bookmarksObserver._itemAddedIndex, testStartIndex);
|
||||
do_check_true(bookmarksObserver._itemAddedURI.equals(uri("http://google.com/")));
|
||||
do_check_eq(bs.getBookmarkURI(newId).spec, "http://google.com/");
|
||||
|
||||
let dateAdded = bs.getItemDateAdded(newId);
|
||||
// dateAdded can equal beforeInsert
|
||||
do_check_true(is_time_ordered(beforeInsert, dateAdded));
|
||||
|
||||
// after just inserting, modified should not be set
|
||||
let lastModified = bs.getItemLastModified(newId);
|
||||
do_check_eq(lastModified, dateAdded);
|
||||
|
||||
// The time before we set the title, in microseconds.
|
||||
let beforeSetTitle = Date.now() * 1000;
|
||||
do_check_true(beforeSetTitle >= beforeInsert);
|
||||
|
||||
// Workaround possible VM timers issues moving lastModified and dateAdded
|
||||
// to the past.
|
||||
lastModified -= 1000;
|
||||
bs.setItemLastModified(newId, lastModified);
|
||||
dateAdded -= 1000;
|
||||
bs.setItemDateAdded(newId, dateAdded);
|
||||
|
||||
// set bookmark title
|
||||
bs.setItemTitle(newId, "Google");
|
||||
do_check_eq(bookmarksObserver._itemChangedId, newId);
|
||||
do_check_eq(bookmarksObserver._itemChangedProperty, "title");
|
||||
do_check_eq(bookmarksObserver._itemChangedValue, "Google");
|
||||
|
||||
// check that dateAdded hasn't changed
|
||||
let dateAdded2 = bs.getItemDateAdded(newId);
|
||||
do_check_eq(dateAdded2, dateAdded);
|
||||
|
||||
// check lastModified after we set the title
|
||||
let lastModified2 = bs.getItemLastModified(newId);
|
||||
do_print("test setItemTitle");
|
||||
do_print("dateAdded = " + dateAdded);
|
||||
do_print("beforeSetTitle = " + beforeSetTitle);
|
||||
do_print("lastModified = " + lastModified);
|
||||
do_print("lastModified2 = " + lastModified2);
|
||||
do_check_true(is_time_ordered(lastModified, lastModified2));
|
||||
do_check_true(is_time_ordered(dateAdded, lastModified2));
|
||||
|
||||
// get item title
|
||||
let title = bs.getItemTitle(newId);
|
||||
do_check_eq(title, "Google");
|
||||
|
||||
// test getItemType for bookmarks
|
||||
do_check_eq(bs.getItemType(newId), bs.TYPE_BOOKMARK);
|
||||
|
||||
// get item title bad input
|
||||
try {
|
||||
bs.getItemTitle(-3);
|
||||
do_throw("getItemTitle accepted bad input");
|
||||
} catch (ex) {}
|
||||
|
||||
// get the folder that the bookmark is in
|
||||
let folderId = bs.getFolderIdForItem(newId);
|
||||
do_check_eq(folderId, testRoot);
|
||||
|
||||
// test getItemIndex for bookmarks
|
||||
do_check_eq(bs.getItemIndex(newId), testStartIndex);
|
||||
|
||||
// create a folder at a specific index
|
||||
let workFolder = bs.createFolder(testRoot, "Work", 0);
|
||||
do_check_eq(bookmarksObserver._itemAddedId, workFolder);
|
||||
do_check_eq(bookmarksObserver._itemAddedParent, testRoot);
|
||||
do_check_eq(bookmarksObserver._itemAddedIndex, 0);
|
||||
do_check_eq(bookmarksObserver._itemAddedURI, null);
|
||||
|
||||
do_check_eq(bs.getItemTitle(workFolder), "Work");
|
||||
bs.setItemTitle(workFolder, "Work #");
|
||||
do_check_eq(bs.getItemTitle(workFolder), "Work #");
|
||||
|
||||
// add item into subfolder, specifying index
|
||||
let newId2 = bs.insertBookmark(workFolder,
|
||||
uri("http://developer.mozilla.org/"),
|
||||
0, "");
|
||||
do_check_eq(bookmarksObserver._itemAddedId, newId2);
|
||||
do_check_eq(bookmarksObserver._itemAddedParent, workFolder);
|
||||
do_check_eq(bookmarksObserver._itemAddedIndex, 0);
|
||||
|
||||
// change item
|
||||
bs.setItemTitle(newId2, "DevMo");
|
||||
do_check_eq(bookmarksObserver._itemChangedProperty, "title");
|
||||
|
||||
// insert item into subfolder
|
||||
let newId3 = bs.insertBookmark(workFolder,
|
||||
uri("http://msdn.microsoft.com/"),
|
||||
bs.DEFAULT_INDEX, "");
|
||||
do_check_eq(bookmarksObserver._itemAddedId, newId3);
|
||||
do_check_eq(bookmarksObserver._itemAddedParent, workFolder);
|
||||
do_check_eq(bookmarksObserver._itemAddedIndex, 1);
|
||||
|
||||
// change item
|
||||
bs.setItemTitle(newId3, "MSDN");
|
||||
do_check_eq(bookmarksObserver._itemChangedProperty, "title");
|
||||
|
||||
// remove item
|
||||
bs.removeItem(newId2);
|
||||
do_check_eq(bookmarksObserver._itemRemovedId, newId2);
|
||||
do_check_eq(bookmarksObserver._itemRemovedFolder, workFolder);
|
||||
do_check_eq(bookmarksObserver._itemRemovedIndex, 0);
|
||||
|
||||
// insert item into subfolder
|
||||
let newId4 = bs.insertBookmark(workFolder,
|
||||
uri("http://developer.mozilla.org/"),
|
||||
bs.DEFAULT_INDEX, "");
|
||||
do_check_eq(bookmarksObserver._itemAddedId, newId4);
|
||||
do_check_eq(bookmarksObserver._itemAddedParent, workFolder);
|
||||
do_check_eq(bookmarksObserver._itemAddedIndex, 1);
|
||||
|
||||
// create folder
|
||||
let homeFolder = bs.createFolder(testRoot, "Home", bs.DEFAULT_INDEX);
|
||||
do_check_eq(bookmarksObserver._itemAddedId, homeFolder);
|
||||
do_check_eq(bookmarksObserver._itemAddedParent, testRoot);
|
||||
do_check_eq(bookmarksObserver._itemAddedIndex, 2);
|
||||
|
||||
// insert item
|
||||
let newId5 = bs.insertBookmark(homeFolder, uri("http://espn.com/"),
|
||||
bs.DEFAULT_INDEX, "");
|
||||
do_check_eq(bookmarksObserver._itemAddedId, newId5);
|
||||
do_check_eq(bookmarksObserver._itemAddedParent, homeFolder);
|
||||
do_check_eq(bookmarksObserver._itemAddedIndex, 0);
|
||||
|
||||
// change item
|
||||
bs.setItemTitle(newId5, "ESPN");
|
||||
do_check_eq(bookmarksObserver._itemChangedId, newId5);
|
||||
do_check_eq(bookmarksObserver._itemChangedProperty, "title");
|
||||
|
||||
// insert query item
|
||||
let uri6 = uri("place:domain=google.com&type="+
|
||||
Ci.nsINavHistoryQueryOptions.RESULTS_AS_SITE_QUERY);
|
||||
let newId6 = bs.insertBookmark(testRoot, uri6, bs.DEFAULT_INDEX, "");
|
||||
do_check_eq(bookmarksObserver._itemAddedParent, testRoot);
|
||||
do_check_eq(bookmarksObserver._itemAddedIndex, 3);
|
||||
|
||||
// change item
|
||||
bs.setItemTitle(newId6, "Google Sites");
|
||||
do_check_eq(bookmarksObserver._itemChangedProperty, "title");
|
||||
|
||||
// test getIdForItemAt
|
||||
do_check_eq(bs.getIdForItemAt(testRoot, 0), workFolder);
|
||||
// wrong parent, should return -1
|
||||
do_check_eq(bs.getIdForItemAt(1337, 0), -1);
|
||||
// wrong index, should return -1
|
||||
do_check_eq(bs.getIdForItemAt(testRoot, 1337), -1);
|
||||
// wrong parent and index, should return -1
|
||||
do_check_eq(bs.getIdForItemAt(1337, 1337), -1);
|
||||
|
||||
// move folder, appending, to different folder
|
||||
let oldParentCC = getChildCount(testRoot);
|
||||
bs.moveItem(workFolder, homeFolder, bs.DEFAULT_INDEX);
|
||||
do_check_eq(bookmarksObserver._itemMovedId, workFolder);
|
||||
do_check_eq(bookmarksObserver._itemMovedOldParent, testRoot);
|
||||
do_check_eq(bookmarksObserver._itemMovedOldIndex, 0);
|
||||
do_check_eq(bookmarksObserver._itemMovedNewParent, homeFolder);
|
||||
do_check_eq(bookmarksObserver._itemMovedNewIndex, 1);
|
||||
|
||||
// test that the new index is properly stored
|
||||
do_check_eq(bs.getItemIndex(workFolder), 1);
|
||||
do_check_eq(bs.getFolderIdForItem(workFolder), homeFolder);
|
||||
|
||||
// try to get index of the item from within the old parent folder
|
||||
// check that it has been really removed from there
|
||||
do_check_neq(bs.getIdForItemAt(testRoot, 0), workFolder);
|
||||
// check the last item from within the old parent folder
|
||||
do_check_neq(bs.getIdForItemAt(testRoot, -1), workFolder);
|
||||
// check the index of the item within the new parent folder
|
||||
do_check_eq(bs.getIdForItemAt(homeFolder, 1), workFolder);
|
||||
// try to get index of the last item within the new parent folder
|
||||
do_check_eq(bs.getIdForItemAt(homeFolder, -1), workFolder);
|
||||
// XXX expose FolderCount, and check that the old parent has one less child?
|
||||
do_check_eq(getChildCount(testRoot), oldParentCC-1);
|
||||
|
||||
// move item, appending, to different folder
|
||||
bs.moveItem(newId5, testRoot, bs.DEFAULT_INDEX);
|
||||
do_check_eq(bookmarksObserver._itemMovedId, newId5);
|
||||
do_check_eq(bookmarksObserver._itemMovedOldParent, homeFolder);
|
||||
do_check_eq(bookmarksObserver._itemMovedOldIndex, 0);
|
||||
do_check_eq(bookmarksObserver._itemMovedNewParent, testRoot);
|
||||
do_check_eq(bookmarksObserver._itemMovedNewIndex, 3);
|
||||
|
||||
// test get folder's index
|
||||
let tmpFolder = bs.createFolder(testRoot, "tmp", 2);
|
||||
do_check_eq(bs.getItemIndex(tmpFolder), 2);
|
||||
|
||||
// test setKeywordForBookmark
|
||||
let kwTestItemId = bs.insertBookmark(testRoot, uri("http://keywordtest.com"),
|
||||
bs.DEFAULT_INDEX, "");
|
||||
bs.setKeywordForBookmark(kwTestItemId, "bar");
|
||||
|
||||
// test getKeywordForBookmark
|
||||
let k = bs.getKeywordForBookmark(kwTestItemId);
|
||||
do_check_eq("bar", k);
|
||||
|
||||
// test getURIForKeyword
|
||||
let u = bs.getURIForKeyword("bar");
|
||||
do_check_eq("http://keywordtest.com/", u.spec);
|
||||
|
||||
// test removeFolderChildren
|
||||
// 1) add/remove each child type (bookmark, separator, folder)
|
||||
tmpFolder = bs.createFolder(testRoot, "removeFolderChildren",
|
||||
bs.DEFAULT_INDEX);
|
||||
bs.insertBookmark(tmpFolder, uri("http://foo9.com/"), bs.DEFAULT_INDEX, "");
|
||||
bs.createFolder(tmpFolder, "subfolder", bs.DEFAULT_INDEX);
|
||||
bs.insertSeparator(tmpFolder, bs.DEFAULT_INDEX);
|
||||
// 2) confirm that folder has 3 children
|
||||
let options = hs.getNewQueryOptions();
|
||||
let query = hs.getNewQuery();
|
||||
query.setFolders([tmpFolder], 1);
|
||||
try {
|
||||
let result = hs.executeQuery(query, options);
|
||||
let rootNode = result.root;
|
||||
rootNode.containerOpen = true;
|
||||
do_check_eq(rootNode.childCount, 3);
|
||||
rootNode.containerOpen = false;
|
||||
} catch (ex) {
|
||||
do_throw("test removeFolderChildren() - querying for children failed: " + ex);
|
||||
}
|
||||
// 3) remove all children
|
||||
bs.removeFolderChildren(tmpFolder);
|
||||
// 4) confirm that folder has 0 children
|
||||
try {
|
||||
result = hs.executeQuery(query, options);
|
||||
let rootNode = result.root;
|
||||
rootNode.containerOpen = true;
|
||||
do_check_eq(rootNode.childCount, 0);
|
||||
rootNode.containerOpen = false;
|
||||
} catch (ex) {
|
||||
do_throw("removeFolderChildren(): " + ex);
|
||||
}
|
||||
|
||||
// XXX - test folderReadOnly
|
||||
|
||||
// test bookmark id in query output
|
||||
try {
|
||||
options = hs.getNewQueryOptions();
|
||||
query = hs.getNewQuery();
|
||||
query.setFolders([testRoot], 1);
|
||||
let result = hs.executeQuery(query, options);
|
||||
let rootNode = result.root;
|
||||
rootNode.containerOpen = true;
|
||||
let cc = rootNode.childCount;
|
||||
do_print("bookmark itemId test: CC = " + cc);
|
||||
do_check_true(cc > 0);
|
||||
for (let i=0; i < cc; ++i) {
|
||||
let node = rootNode.getChild(i);
|
||||
if (node.type == node.RESULT_TYPE_FOLDER ||
|
||||
node.type == node.RESULT_TYPE_URI ||
|
||||
node.type == node.RESULT_TYPE_SEPARATOR ||
|
||||
node.type == node.RESULT_TYPE_QUERY) {
|
||||
do_check_true(node.itemId > 0);
|
||||
}
|
||||
else {
|
||||
do_check_eq(node.itemId, -1);
|
||||
}
|
||||
}
|
||||
rootNode.containerOpen = false;
|
||||
}
|
||||
catch (ex) {
|
||||
do_throw("bookmarks query: " + ex);
|
||||
}
|
||||
|
||||
// test that multiple bookmarks with same URI show up right in bookmark
|
||||
// folder queries, todo: also to do for complex folder queries
|
||||
try {
|
||||
// test uri
|
||||
let mURI = uri("http://multiple.uris.in.query");
|
||||
|
||||
let testFolder = bs.createFolder(testRoot, "test Folder", bs.DEFAULT_INDEX);
|
||||
// add 2 bookmarks
|
||||
bs.insertBookmark(testFolder, mURI, bs.DEFAULT_INDEX, "title 1");
|
||||
bs.insertBookmark(testFolder, mURI, bs.DEFAULT_INDEX, "title 2");
|
||||
|
||||
// query
|
||||
options = hs.getNewQueryOptions();
|
||||
query = hs.getNewQuery();
|
||||
query.setFolders([testFolder], 1);
|
||||
let result = hs.executeQuery(query, options);
|
||||
let rootNode = result.root;
|
||||
rootNode.containerOpen = true;
|
||||
let cc = rootNode.childCount;
|
||||
do_check_eq(cc, 2);
|
||||
do_check_eq(rootNode.getChild(0).title, "title 1");
|
||||
do_check_eq(rootNode.getChild(1).title, "title 2");
|
||||
rootNode.containerOpen = false;
|
||||
}
|
||||
catch (ex) {
|
||||
do_throw("bookmarks query: " + ex);
|
||||
}
|
||||
|
||||
// test change bookmark uri
|
||||
let newId10 = bs.insertBookmark(testRoot, uri("http://foo10.com/"),
|
||||
bs.DEFAULT_INDEX, "");
|
||||
dateAdded = bs.getItemDateAdded(newId10);
|
||||
// after just inserting, modified should not be set
|
||||
lastModified = bs.getItemLastModified(newId10);
|
||||
do_check_eq(lastModified, dateAdded);
|
||||
|
||||
// Workaround possible VM timers issues moving lastModified and dateAdded
|
||||
// to the past.
|
||||
lastModified -= 1000;
|
||||
bs.setItemLastModified(newId10, lastModified);
|
||||
dateAdded -= 1000;
|
||||
bs.setItemDateAdded(newId10, dateAdded);
|
||||
|
||||
bs.changeBookmarkURI(newId10, uri("http://foo11.com/"));
|
||||
|
||||
// check that lastModified is set after we change the bookmark uri
|
||||
lastModified2 = bs.getItemLastModified(newId10);
|
||||
do_print("test changeBookmarkURI");
|
||||
do_print("dateAdded = " + dateAdded);
|
||||
do_print("lastModified = " + lastModified);
|
||||
do_print("lastModified2 = " + lastModified2);
|
||||
do_check_true(is_time_ordered(lastModified, lastModified2));
|
||||
do_check_true(is_time_ordered(dateAdded, lastModified2));
|
||||
|
||||
do_check_eq(bookmarksObserver._itemChangedId, newId10);
|
||||
do_check_eq(bookmarksObserver._itemChangedProperty, "uri");
|
||||
do_check_eq(bookmarksObserver._itemChangedValue, "http://foo11.com/");
|
||||
do_check_eq(bookmarksObserver._itemChangedOldValue, "http://foo10.com/");
|
||||
|
||||
// test getBookmarkURI
|
||||
let newId11 = bs.insertBookmark(testRoot, uri("http://foo11.com/"),
|
||||
bs.DEFAULT_INDEX, "");
|
||||
let bmURI = bs.getBookmarkURI(newId11);
|
||||
do_check_eq("http://foo11.com/", bmURI.spec);
|
||||
|
||||
// test getBookmarkURI with non-bookmark items
|
||||
try {
|
||||
bs.getBookmarkURI(testRoot);
|
||||
do_throw("getBookmarkURI() should throw for non-bookmark items!");
|
||||
} catch (ex) {}
|
||||
|
||||
// test getItemIndex
|
||||
let newId12 = bs.insertBookmark(testRoot, uri("http://foo11.com/"), 1, "");
|
||||
let bmIndex = bs.getItemIndex(newId12);
|
||||
do_check_eq(1, bmIndex);
|
||||
|
||||
// insert a bookmark with title ZZZXXXYYY and then search for it.
|
||||
// this test confirms that we can find bookmarks that we haven't visited
|
||||
// (which are "hidden") and that we can find by title.
|
||||
// see bug #369887 for more details
|
||||
let newId13 = bs.insertBookmark(testRoot, uri("http://foobarcheese.com/"),
|
||||
bs.DEFAULT_INDEX, "");
|
||||
do_check_eq(bookmarksObserver._itemAddedId, newId13);
|
||||
do_check_eq(bookmarksObserver._itemAddedParent, testRoot);
|
||||
do_check_eq(bookmarksObserver._itemAddedIndex, 11);
|
||||
|
||||
// set bookmark title
|
||||
bs.setItemTitle(newId13, "ZZZXXXYYY");
|
||||
do_check_eq(bookmarksObserver._itemChangedId, newId13);
|
||||
do_check_eq(bookmarksObserver._itemChangedProperty, "title");
|
||||
do_check_eq(bookmarksObserver._itemChangedValue, "ZZZXXXYYY");
|
||||
|
||||
// check if setting an item annotation triggers onItemChanged
|
||||
bookmarksObserver._itemChangedId = -1;
|
||||
anno.setItemAnnotation(newId3, "test-annotation", "foo", 0, 0);
|
||||
do_check_eq(bookmarksObserver._itemChangedId, newId3);
|
||||
do_check_eq(bookmarksObserver._itemChangedProperty, "test-annotation");
|
||||
do_check_true(bookmarksObserver._itemChanged_isAnnotationProperty);
|
||||
do_check_eq(bookmarksObserver._itemChangedValue, "");
|
||||
|
||||
// test search on bookmark title ZZZXXXYYY
|
||||
try {
|
||||
options = hs.getNewQueryOptions();
|
||||
options.excludeQueries = 1;
|
||||
options.queryType = Ci.nsINavHistoryQueryOptions.QUERY_TYPE_BOOKMARKS;
|
||||
query = hs.getNewQuery();
|
||||
query.searchTerms = "ZZZXXXYYY";
|
||||
let result = hs.executeQuery(query, options);
|
||||
let rootNode = result.root;
|
||||
rootNode.containerOpen = true;
|
||||
let cc = rootNode.childCount;
|
||||
do_check_eq(cc, 1);
|
||||
let node = rootNode.getChild(0);
|
||||
do_check_eq(node.title, "ZZZXXXYYY");
|
||||
do_check_true(node.itemId > 0);
|
||||
rootNode.containerOpen = false;
|
||||
}
|
||||
catch (ex) {
|
||||
do_throw("bookmarks query: " + ex);
|
||||
}
|
||||
|
||||
// test dateAdded and lastModified properties
|
||||
// for a search query
|
||||
try {
|
||||
options = hs.getNewQueryOptions();
|
||||
options.excludeQueries = 1;
|
||||
options.queryType = Ci.nsINavHistoryQueryOptions.QUERY_TYPE_BOOKMARKS;
|
||||
query = hs.getNewQuery();
|
||||
query.searchTerms = "ZZZXXXYYY";
|
||||
let result = hs.executeQuery(query, options);
|
||||
let rootNode = result.root;
|
||||
rootNode.containerOpen = true;
|
||||
let cc = rootNode.childCount;
|
||||
do_check_eq(cc, 1);
|
||||
let node = rootNode.getChild(0);
|
||||
|
||||
do_check_eq(typeof node.dateAdded, "number");
|
||||
do_check_true(node.dateAdded > 0);
|
||||
|
||||
do_check_eq(typeof node.lastModified, "number");
|
||||
do_check_true(node.lastModified > 0);
|
||||
|
||||
rootNode.containerOpen = false;
|
||||
}
|
||||
catch (ex) {
|
||||
do_throw("bookmarks query: " + ex);
|
||||
}
|
||||
|
||||
// test dateAdded and lastModified properties
|
||||
// for a folder query
|
||||
try {
|
||||
options = hs.getNewQueryOptions();
|
||||
query = hs.getNewQuery();
|
||||
query.setFolders([testRoot], 1);
|
||||
let result = hs.executeQuery(query, options);
|
||||
let rootNode = result.root;
|
||||
rootNode.containerOpen = true;
|
||||
let cc = rootNode.childCount;
|
||||
do_check_true(cc > 0);
|
||||
for (let i = 0; i < cc; i++) {
|
||||
let node = rootNode.getChild(i);
|
||||
|
||||
if (node.type == node.RESULT_TYPE_URI) {
|
||||
do_check_eq(typeof node.dateAdded, "number");
|
||||
do_check_true(node.dateAdded > 0);
|
||||
|
||||
do_check_eq(typeof node.lastModified, "number");
|
||||
do_check_true(node.lastModified > 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
rootNode.containerOpen = false;
|
||||
}
|
||||
catch (ex) {
|
||||
do_throw("bookmarks query: " + ex);
|
||||
}
|
||||
|
||||
// check setItemLastModified() and setItemDateAdded()
|
||||
let newId14 = bs.insertBookmark(testRoot, uri("http://bar.tld/"),
|
||||
bs.DEFAULT_INDEX, "");
|
||||
dateAdded = bs.getItemDateAdded(newId14);
|
||||
lastModified = bs.getItemLastModified(newId14);
|
||||
do_check_eq(lastModified, dateAdded);
|
||||
bs.setItemLastModified(newId14, 1234000000000000);
|
||||
let fakeLastModified = bs.getItemLastModified(newId14);
|
||||
do_check_eq(fakeLastModified, 1234000000000000);
|
||||
bs.setItemDateAdded(newId14, 4321000000000000);
|
||||
let fakeDateAdded = bs.getItemDateAdded(newId14);
|
||||
do_check_eq(fakeDateAdded, 4321000000000000);
|
||||
|
||||
// ensure that removing an item removes its annotations
|
||||
do_check_true(anno.itemHasAnnotation(newId3, "test-annotation"));
|
||||
bs.removeItem(newId3);
|
||||
do_check_false(anno.itemHasAnnotation(newId3, "test-annotation"));
|
||||
|
||||
// bug 378820
|
||||
let uri1 = uri("http://foo.tld/a");
|
||||
bs.insertBookmark(testRoot, uri1, bs.DEFAULT_INDEX, "");
|
||||
yield PlacesTestUtils.addVisits(uri1);
|
||||
|
||||
// bug 646993 - test bookmark titles longer than the maximum allowed length
|
||||
let title15 = Array(TITLE_LENGTH_MAX + 5).join("X");
|
||||
let title15expected = title15.substring(0, TITLE_LENGTH_MAX);
|
||||
let newId15 = bs.insertBookmark(testRoot, uri("http://evil.com/"),
|
||||
bs.DEFAULT_INDEX, title15);
|
||||
|
||||
do_check_eq(bs.getItemTitle(newId15).length,
|
||||
title15expected.length);
|
||||
do_check_eq(bookmarksObserver._itemAddedTitle, title15expected);
|
||||
// test title length after updates
|
||||
bs.setItemTitle(newId15, title15 + " updated");
|
||||
do_check_eq(bs.getItemTitle(newId15).length,
|
||||
title15expected.length);
|
||||
do_check_eq(bookmarksObserver._itemChangedId, newId15);
|
||||
do_check_eq(bookmarksObserver._itemChangedProperty, "title");
|
||||
do_check_eq(bookmarksObserver._itemChangedValue, title15expected);
|
||||
|
||||
testSimpleFolderResult();
|
||||
});
|
||||
|
||||
function testSimpleFolderResult() {
|
||||
// the time before we create a folder, in microseconds
|
||||
// Workaround possible VM timers issues subtracting 1us.
|
||||
let beforeCreate = Date.now() * 1000 - 1;
|
||||
do_check_true(beforeCreate > 0);
|
||||
|
||||
// create a folder
|
||||
let parent = bs.createFolder(root, "test", bs.DEFAULT_INDEX);
|
||||
|
||||
let dateCreated = bs.getItemDateAdded(parent);
|
||||
do_print("check that the folder was created with a valid dateAdded");
|
||||
do_print("beforeCreate = " + beforeCreate);
|
||||
do_print("dateCreated = " + dateCreated);
|
||||
do_check_true(is_time_ordered(beforeCreate, dateCreated));
|
||||
|
||||
// the time before we insert, in microseconds
|
||||
// Workaround possible VM timers issues subtracting 1ms.
|
||||
let beforeInsert = Date.now() * 1000 - 1;
|
||||
do_check_true(beforeInsert > 0);
|
||||
|
||||
// insert a separator
|
||||
let sep = bs.insertSeparator(parent, bs.DEFAULT_INDEX);
|
||||
|
||||
let dateAdded = bs.getItemDateAdded(sep);
|
||||
do_print("check that the separator was created with a valid dateAdded");
|
||||
do_print("beforeInsert = " + beforeInsert);
|
||||
do_print("dateAdded = " + dateAdded);
|
||||
do_check_true(is_time_ordered(beforeInsert, dateAdded));
|
||||
|
||||
// re-set item title separately so can test nodes' last modified
|
||||
let item = bs.insertBookmark(parent, uri("about:blank"),
|
||||
bs.DEFAULT_INDEX, "");
|
||||
bs.setItemTitle(item, "test bookmark");
|
||||
|
||||
// see above
|
||||
let folder = bs.createFolder(parent, "test folder", bs.DEFAULT_INDEX);
|
||||
bs.setItemTitle(folder, "test folder");
|
||||
|
||||
let longName = Array(TITLE_LENGTH_MAX + 5).join("A");
|
||||
let folderLongName = bs.createFolder(parent, longName, bs.DEFAULT_INDEX);
|
||||
do_check_eq(bookmarksObserver._itemAddedTitle, longName.substring(0, TITLE_LENGTH_MAX));
|
||||
|
||||
let options = hs.getNewQueryOptions();
|
||||
let query = hs.getNewQuery();
|
||||
query.setFolders([parent], 1);
|
||||
let result = hs.executeQuery(query, options);
|
||||
let rootNode = result.root;
|
||||
rootNode.containerOpen = true;
|
||||
do_check_eq(rootNode.childCount, 4);
|
||||
|
||||
let node = rootNode.getChild(0);
|
||||
do_check_true(node.dateAdded > 0);
|
||||
do_check_eq(node.lastModified, node.dateAdded);
|
||||
do_check_eq(node.itemId, sep);
|
||||
do_check_eq(node.title, "");
|
||||
node = rootNode.getChild(1);
|
||||
do_check_eq(node.itemId, item);
|
||||
do_check_true(node.dateAdded > 0);
|
||||
do_check_true(node.lastModified > 0);
|
||||
do_check_eq(node.title, "test bookmark");
|
||||
node = rootNode.getChild(2);
|
||||
do_check_eq(node.itemId, folder);
|
||||
do_check_eq(node.title, "test folder");
|
||||
do_check_true(node.dateAdded > 0);
|
||||
do_check_true(node.lastModified > 0);
|
||||
node = rootNode.getChild(3);
|
||||
do_check_eq(node.itemId, folderLongName);
|
||||
do_check_eq(node.title, longName.substring(0, TITLE_LENGTH_MAX));
|
||||
do_check_true(node.dateAdded > 0);
|
||||
do_check_true(node.lastModified > 0);
|
||||
|
||||
// update with another long title
|
||||
bs.setItemTitle(folderLongName, longName + " updated");
|
||||
do_check_eq(bookmarksObserver._itemChangedId, folderLongName);
|
||||
do_check_eq(bookmarksObserver._itemChangedProperty, "title");
|
||||
do_check_eq(bookmarksObserver._itemChangedValue, longName.substring(0, TITLE_LENGTH_MAX));
|
||||
|
||||
node = rootNode.getChild(3);
|
||||
do_check_eq(node.title, longName.substring(0, TITLE_LENGTH_MAX));
|
||||
|
||||
rootNode.containerOpen = false;
|
||||
}
|
||||
|
||||
function getChildCount(aFolderId) {
|
||||
let cc = -1;
|
||||
try {
|
||||
let options = hs.getNewQueryOptions();
|
||||
let query = hs.getNewQuery();
|
||||
query.setFolders([aFolderId], 1);
|
||||
let result = hs.executeQuery(query, options);
|
||||
let rootNode = result.root;
|
||||
rootNode.containerOpen = true;
|
||||
cc = rootNode.childCount;
|
||||
rootNode.containerOpen = false;
|
||||
} catch (ex) {
|
||||
do_throw("getChildCount failed: " + ex);
|
||||
}
|
||||
return cc;
|
||||
}
|
||||
|
|
@ -0,0 +1,116 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
add_task(function* test_eraseEverything() {
|
||||
yield PlacesTestUtils.addVisits({ uri: NetUtil.newURI("http://example.com/") });
|
||||
yield PlacesTestUtils.addVisits({ uri: NetUtil.newURI("http://mozilla.org/") });
|
||||
let frecencyForExample = frecencyForUrl("http://example.com/");
|
||||
let frecencyForMozilla = frecencyForUrl("http://example.com/");
|
||||
Assert.ok(frecencyForExample > 0);
|
||||
Assert.ok(frecencyForMozilla > 0);
|
||||
let unfiledFolder = yield PlacesUtils.bookmarks.insert({ parentGuid: PlacesUtils.bookmarks.unfiledGuid,
|
||||
type: PlacesUtils.bookmarks.TYPE_FOLDER });
|
||||
checkBookmarkObject(unfiledFolder);
|
||||
let unfiledBookmark = yield PlacesUtils.bookmarks.insert({ parentGuid: PlacesUtils.bookmarks.unfiledGuid,
|
||||
type: PlacesUtils.bookmarks.TYPE_BOOKMARK,
|
||||
url: "http://example.com/" });
|
||||
checkBookmarkObject(unfiledBookmark);
|
||||
let unfiledBookmarkInFolder =
|
||||
yield PlacesUtils.bookmarks.insert({ parentGuid: unfiledFolder.guid,
|
||||
type: PlacesUtils.bookmarks.TYPE_BOOKMARK,
|
||||
url: "http://mozilla.org/" });
|
||||
checkBookmarkObject(unfiledBookmarkInFolder);
|
||||
PlacesUtils.annotations.setItemAnnotation((yield PlacesUtils.promiseItemId(unfiledBookmarkInFolder.guid)),
|
||||
"testanno1", "testvalue1", 0, 0);
|
||||
|
||||
let menuFolder = yield PlacesUtils.bookmarks.insert({ parentGuid: PlacesUtils.bookmarks.menuGuid,
|
||||
type: PlacesUtils.bookmarks.TYPE_FOLDER });
|
||||
checkBookmarkObject(menuFolder);
|
||||
let menuBookmark = yield PlacesUtils.bookmarks.insert({ parentGuid: PlacesUtils.bookmarks.menuGuid,
|
||||
type: PlacesUtils.bookmarks.TYPE_BOOKMARK,
|
||||
url: "http://example.com/" });
|
||||
checkBookmarkObject(menuBookmark);
|
||||
let menuBookmarkInFolder =
|
||||
yield PlacesUtils.bookmarks.insert({ parentGuid: menuFolder.guid,
|
||||
type: PlacesUtils.bookmarks.TYPE_BOOKMARK,
|
||||
url: "http://mozilla.org/" });
|
||||
checkBookmarkObject(menuBookmarkInFolder);
|
||||
PlacesUtils.annotations.setItemAnnotation((yield PlacesUtils.promiseItemId(menuBookmarkInFolder.guid)),
|
||||
"testanno1", "testvalue1", 0, 0);
|
||||
|
||||
let toolbarFolder = yield PlacesUtils.bookmarks.insert({ parentGuid: PlacesUtils.bookmarks.toolbarGuid,
|
||||
type: PlacesUtils.bookmarks.TYPE_FOLDER });
|
||||
checkBookmarkObject(toolbarFolder);
|
||||
let toolbarBookmark = yield PlacesUtils.bookmarks.insert({ parentGuid: PlacesUtils.bookmarks.toolbarGuid,
|
||||
type: PlacesUtils.bookmarks.TYPE_BOOKMARK,
|
||||
url: "http://example.com/" });
|
||||
checkBookmarkObject(toolbarBookmark);
|
||||
let toolbarBookmarkInFolder =
|
||||
yield PlacesUtils.bookmarks.insert({ parentGuid: toolbarFolder.guid,
|
||||
type: PlacesUtils.bookmarks.TYPE_BOOKMARK,
|
||||
url: "http://mozilla.org/" });
|
||||
checkBookmarkObject(toolbarBookmarkInFolder);
|
||||
PlacesUtils.annotations.setItemAnnotation((yield PlacesUtils.promiseItemId(toolbarBookmarkInFolder.guid)),
|
||||
"testanno1", "testvalue1", 0, 0);
|
||||
|
||||
yield PlacesTestUtils.promiseAsyncUpdates();
|
||||
Assert.ok(frecencyForUrl("http://example.com/") > frecencyForExample);
|
||||
Assert.ok(frecencyForUrl("http://example.com/") > frecencyForMozilla);
|
||||
|
||||
yield PlacesUtils.bookmarks.eraseEverything();
|
||||
|
||||
Assert.equal(frecencyForUrl("http://example.com/"), frecencyForExample);
|
||||
Assert.equal(frecencyForUrl("http://example.com/"), frecencyForMozilla);
|
||||
|
||||
// Check there are no orphan annotations.
|
||||
let conn = yield PlacesUtils.promiseDBConnection();
|
||||
let annoAttrs = yield conn.execute(`SELECT id, name FROM moz_anno_attributes`);
|
||||
// Bug 1306445 will eventually remove the mobile root anno.
|
||||
Assert.equal(annoAttrs.length, 1);
|
||||
Assert.equal(annoAttrs[0].getResultByName("name"), PlacesUtils.MOBILE_ROOT_ANNO);
|
||||
let annos = rows = yield conn.execute(`SELECT item_id, anno_attribute_id FROM moz_items_annos`);
|
||||
Assert.equal(annos.length, 1);
|
||||
Assert.equal(annos[0].getResultByName("item_id"), PlacesUtils.mobileFolderId);
|
||||
Assert.equal(annos[0].getResultByName("anno_attribute_id"), annoAttrs[0].getResultByName("id"));
|
||||
});
|
||||
|
||||
add_task(function* test_eraseEverything_roots() {
|
||||
yield PlacesUtils.bookmarks.eraseEverything();
|
||||
|
||||
// Ensure the roots have not been removed.
|
||||
Assert.ok(yield PlacesUtils.bookmarks.fetch(PlacesUtils.bookmarks.unfiledGuid));
|
||||
Assert.ok(yield PlacesUtils.bookmarks.fetch(PlacesUtils.bookmarks.toolbarGuid));
|
||||
Assert.ok(yield PlacesUtils.bookmarks.fetch(PlacesUtils.bookmarks.menuGuid));
|
||||
Assert.ok(yield PlacesUtils.bookmarks.fetch(PlacesUtils.bookmarks.tagsGuid));
|
||||
Assert.ok(yield PlacesUtils.bookmarks.fetch(PlacesUtils.bookmarks.rootGuid));
|
||||
});
|
||||
|
||||
add_task(function* test_eraseEverything_reparented() {
|
||||
// Create a folder with 1 bookmark in it...
|
||||
let folder1 = yield PlacesUtils.bookmarks.insert({
|
||||
parentGuid: PlacesUtils.bookmarks.toolbarGuid,
|
||||
type: PlacesUtils.bookmarks.TYPE_FOLDER
|
||||
});
|
||||
let bookmark1 = yield PlacesUtils.bookmarks.insert({
|
||||
parentGuid: folder1.guid,
|
||||
url: "http://example.com/"
|
||||
});
|
||||
// ...and a second folder.
|
||||
let folder2 = yield PlacesUtils.bookmarks.insert({
|
||||
parentGuid: PlacesUtils.bookmarks.toolbarGuid,
|
||||
type: PlacesUtils.bookmarks.TYPE_FOLDER
|
||||
});
|
||||
|
||||
// Reparent the bookmark to the 2nd folder.
|
||||
bookmark1.parentGuid = folder2.guid;
|
||||
yield PlacesUtils.bookmarks.update(bookmark1);
|
||||
|
||||
// Erase everything.
|
||||
yield PlacesUtils.bookmarks.eraseEverything();
|
||||
|
||||
// All the above items should no longer be in the GUIDHelper cache.
|
||||
for (let guid of [folder1.guid, bookmark1.guid, folder2.guid]) {
|
||||
yield Assert.rejects(PlacesUtils.promiseItemId(guid),
|
||||
/no item found for the given GUID/);
|
||||
}
|
||||
});
|
||||
|
|
@ -0,0 +1,310 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
var gAccumulator = {
|
||||
get callback() {
|
||||
this.results = [];
|
||||
return result => this.results.push(result);
|
||||
}
|
||||
};
|
||||
|
||||
add_task(function* invalid_input_throws() {
|
||||
Assert.throws(() => PlacesUtils.bookmarks.fetch(),
|
||||
/Input should be a valid object/);
|
||||
Assert.throws(() => PlacesUtils.bookmarks.fetch(null),
|
||||
/Input should be a valid object/);
|
||||
|
||||
Assert.throws(() => PlacesUtils.bookmarks.fetch({ guid: "123456789012",
|
||||
parentGuid: "012345678901" }),
|
||||
/The following properties were expected: index/);
|
||||
Assert.throws(() => PlacesUtils.bookmarks.fetch({ guid: "123456789012",
|
||||
index: 0 }),
|
||||
/The following properties were expected: parentGuid/);
|
||||
|
||||
Assert.throws(() => PlacesUtils.bookmarks.fetch({}),
|
||||
/Unexpected number of conditions provided: 0/);
|
||||
Assert.throws(() => PlacesUtils.bookmarks.fetch({ guid: "123456789012",
|
||||
parentGuid: "012345678901",
|
||||
index: 0 }),
|
||||
/Unexpected number of conditions provided: 2/);
|
||||
Assert.throws(() => PlacesUtils.bookmarks.fetch({ guid: "123456789012",
|
||||
url: "http://example.com"}),
|
||||
/Unexpected number of conditions provided: 2/);
|
||||
|
||||
Assert.throws(() => PlacesUtils.bookmarks.fetch("test"),
|
||||
/Invalid value for property 'guid'/);
|
||||
Assert.throws(() => PlacesUtils.bookmarks.fetch(123),
|
||||
/Invalid value for property 'guid'/);
|
||||
|
||||
Assert.throws(() => PlacesUtils.bookmarks.fetch({ guid: "test" }),
|
||||
/Invalid value for property 'guid'/);
|
||||
Assert.throws(() => PlacesUtils.bookmarks.fetch({ guid: null }),
|
||||
/Invalid value for property 'guid'/);
|
||||
Assert.throws(() => PlacesUtils.bookmarks.fetch({ guid: 123 }),
|
||||
/Invalid value for property 'guid'/);
|
||||
|
||||
Assert.throws(() => PlacesUtils.bookmarks.fetch({ parentGuid: "test",
|
||||
index: 0 }),
|
||||
/Invalid value for property 'parentGuid'/);
|
||||
Assert.throws(() => PlacesUtils.bookmarks.fetch({ parentGuid: null,
|
||||
index: 0 }),
|
||||
/Invalid value for property 'parentGuid'/);
|
||||
Assert.throws(() => PlacesUtils.bookmarks.fetch({ parentGuid: 123,
|
||||
index: 0 }),
|
||||
/Invalid value for property 'parentGuid'/);
|
||||
|
||||
Assert.throws(() => PlacesUtils.bookmarks.fetch({ parentGuid: "123456789012",
|
||||
index: "0" }),
|
||||
/Invalid value for property 'index'/);
|
||||
Assert.throws(() => PlacesUtils.bookmarks.fetch({ parentGuid: "123456789012",
|
||||
index: null }),
|
||||
/Invalid value for property 'index'/);
|
||||
Assert.throws(() => PlacesUtils.bookmarks.fetch({ parentGuid: "123456789012",
|
||||
index: -10 }),
|
||||
/Invalid value for property 'index'/);
|
||||
|
||||
Assert.throws(() => PlacesUtils.bookmarks.fetch({ url: "http://te st/" }),
|
||||
/Invalid value for property 'url'/);
|
||||
Assert.throws(() => PlacesUtils.bookmarks.fetch({ url: null }),
|
||||
/Invalid value for property 'url'/);
|
||||
Assert.throws(() => PlacesUtils.bookmarks.fetch({ url: -10 }),
|
||||
/Invalid value for property 'url'/);
|
||||
|
||||
Assert.throws(() => PlacesUtils.bookmarks.fetch("123456789012", "test"),
|
||||
/onResult callback must be a valid function/);
|
||||
Assert.throws(() => PlacesUtils.bookmarks.fetch("123456789012", {}),
|
||||
/onResult callback must be a valid function/);
|
||||
});
|
||||
|
||||
add_task(function* fetch_nonexistent_guid() {
|
||||
let bm = yield PlacesUtils.bookmarks.fetch({ guid: "123456789012" },
|
||||
gAccumulator.callback);
|
||||
Assert.equal(bm, null);
|
||||
Assert.equal(gAccumulator.results.length, 0);
|
||||
});
|
||||
|
||||
add_task(function* fetch_bookmark() {
|
||||
let bm1 = yield PlacesUtils.bookmarks.insert({ parentGuid: PlacesUtils.bookmarks.unfiledGuid,
|
||||
type: PlacesUtils.bookmarks.TYPE_BOOKMARK,
|
||||
url: "http://example.com/",
|
||||
title: "a bookmark" });
|
||||
checkBookmarkObject(bm1);
|
||||
|
||||
let bm2 = yield PlacesUtils.bookmarks.fetch(bm1.guid,
|
||||
gAccumulator.callback);
|
||||
checkBookmarkObject(bm2);
|
||||
Assert.equal(gAccumulator.results.length, 1);
|
||||
checkBookmarkObject(gAccumulator.results[0]);
|
||||
Assert.deepEqual(gAccumulator.results[0], bm1);
|
||||
|
||||
Assert.deepEqual(bm1, bm2);
|
||||
Assert.equal(bm2.parentGuid, PlacesUtils.bookmarks.unfiledGuid);
|
||||
Assert.equal(bm2.index, 0);
|
||||
Assert.deepEqual(bm2.dateAdded, bm2.lastModified);
|
||||
Assert.equal(bm2.type, PlacesUtils.bookmarks.TYPE_BOOKMARK);
|
||||
Assert.equal(bm2.url.href, "http://example.com/");
|
||||
Assert.equal(bm2.title, "a bookmark");
|
||||
|
||||
yield PlacesUtils.bookmarks.remove(bm1.guid);
|
||||
});
|
||||
|
||||
add_task(function* fetch_bookmar_empty_title() {
|
||||
let bm1 = yield PlacesUtils.bookmarks.insert({ parentGuid: PlacesUtils.bookmarks.unfiledGuid,
|
||||
type: PlacesUtils.bookmarks.TYPE_BOOKMARK,
|
||||
url: "http://example.com/",
|
||||
title: "" });
|
||||
checkBookmarkObject(bm1);
|
||||
|
||||
let bm2 = yield PlacesUtils.bookmarks.fetch(bm1.guid);
|
||||
checkBookmarkObject(bm2);
|
||||
|
||||
Assert.deepEqual(bm1, bm2);
|
||||
Assert.equal(bm2.index, 0);
|
||||
Assert.ok(!("title" in bm2));
|
||||
|
||||
yield PlacesUtils.bookmarks.remove(bm1.guid);
|
||||
});
|
||||
|
||||
add_task(function* fetch_folder() {
|
||||
let bm1 = yield PlacesUtils.bookmarks.insert({ parentGuid: PlacesUtils.bookmarks.unfiledGuid,
|
||||
type: PlacesUtils.bookmarks.TYPE_FOLDER,
|
||||
title: "a folder" });
|
||||
checkBookmarkObject(bm1);
|
||||
|
||||
let bm2 = yield PlacesUtils.bookmarks.fetch(bm1.guid);
|
||||
checkBookmarkObject(bm2);
|
||||
|
||||
Assert.deepEqual(bm1, bm2);
|
||||
Assert.equal(bm2.parentGuid, PlacesUtils.bookmarks.unfiledGuid);
|
||||
Assert.equal(bm2.index, 0);
|
||||
Assert.deepEqual(bm2.dateAdded, bm2.lastModified);
|
||||
Assert.equal(bm2.type, PlacesUtils.bookmarks.TYPE_FOLDER);
|
||||
Assert.equal(bm2.title, "a folder");
|
||||
Assert.ok(!("url" in bm2));
|
||||
|
||||
yield PlacesUtils.bookmarks.remove(bm1.guid);
|
||||
});
|
||||
|
||||
add_task(function* fetch_folder_empty_title() {
|
||||
let bm1 = yield PlacesUtils.bookmarks.insert({ parentGuid: PlacesUtils.bookmarks.unfiledGuid,
|
||||
type: PlacesUtils.bookmarks.TYPE_FOLDER,
|
||||
title: "" });
|
||||
checkBookmarkObject(bm1);
|
||||
|
||||
let bm2 = yield PlacesUtils.bookmarks.fetch(bm1.guid);
|
||||
checkBookmarkObject(bm2);
|
||||
|
||||
Assert.deepEqual(bm1, bm2);
|
||||
Assert.equal(bm2.index, 0);
|
||||
Assert.ok(!("title" in bm2));
|
||||
|
||||
yield PlacesUtils.bookmarks.remove(bm1.guid);
|
||||
});
|
||||
|
||||
add_task(function* fetch_separator() {
|
||||
let bm1 = yield PlacesUtils.bookmarks.insert({ parentGuid: PlacesUtils.bookmarks.unfiledGuid,
|
||||
type: PlacesUtils.bookmarks.TYPE_SEPARATOR });
|
||||
checkBookmarkObject(bm1);
|
||||
|
||||
let bm2 = yield PlacesUtils.bookmarks.fetch(bm1.guid);
|
||||
checkBookmarkObject(bm2);
|
||||
|
||||
Assert.deepEqual(bm1, bm2);
|
||||
Assert.equal(bm2.parentGuid, PlacesUtils.bookmarks.unfiledGuid);
|
||||
Assert.equal(bm2.index, 0);
|
||||
Assert.deepEqual(bm2.dateAdded, bm2.lastModified);
|
||||
Assert.equal(bm2.type, PlacesUtils.bookmarks.TYPE_SEPARATOR);
|
||||
Assert.ok(!("url" in bm2));
|
||||
Assert.ok(!("title" in bm2));
|
||||
|
||||
yield PlacesUtils.bookmarks.remove(bm1.guid);
|
||||
});
|
||||
|
||||
add_task(function* fetch_byposition_nonexisting_parentGuid() {
|
||||
let bm = yield PlacesUtils.bookmarks.fetch({ parentGuid: "123456789012",
|
||||
index: 0 },
|
||||
gAccumulator.callback);
|
||||
Assert.equal(bm, null);
|
||||
Assert.equal(gAccumulator.results.length, 0);
|
||||
});
|
||||
|
||||
add_task(function* fetch_byposition_nonexisting_index() {
|
||||
let bm = yield PlacesUtils.bookmarks.fetch({ parentGuid: PlacesUtils.bookmarks.unfiledGuid,
|
||||
index: 100 },
|
||||
gAccumulator.callback);
|
||||
Assert.equal(bm, null);
|
||||
Assert.equal(gAccumulator.results.length, 0);
|
||||
});
|
||||
|
||||
add_task(function* fetch_byposition() {
|
||||
let bm1 = yield PlacesUtils.bookmarks.insert({ parentGuid: PlacesUtils.bookmarks.unfiledGuid,
|
||||
type: PlacesUtils.bookmarks.TYPE_BOOKMARK,
|
||||
url: "http://example.com/",
|
||||
title: "a bookmark" });
|
||||
checkBookmarkObject(bm1);
|
||||
|
||||
let bm2 = yield PlacesUtils.bookmarks.fetch({ parentGuid: bm1.parentGuid,
|
||||
index: bm1.index },
|
||||
gAccumulator.callback);
|
||||
checkBookmarkObject(bm2);
|
||||
Assert.equal(gAccumulator.results.length, 1);
|
||||
checkBookmarkObject(gAccumulator.results[0]);
|
||||
Assert.deepEqual(gAccumulator.results[0], bm1);
|
||||
|
||||
Assert.deepEqual(bm1, bm2);
|
||||
Assert.equal(bm2.parentGuid, PlacesUtils.bookmarks.unfiledGuid);
|
||||
Assert.equal(bm2.index, 0);
|
||||
Assert.deepEqual(bm2.dateAdded, bm2.lastModified);
|
||||
Assert.equal(bm2.type, PlacesUtils.bookmarks.TYPE_BOOKMARK);
|
||||
Assert.equal(bm2.url.href, "http://example.com/");
|
||||
Assert.equal(bm2.title, "a bookmark");
|
||||
});
|
||||
|
||||
add_task(function* fetch_byposition_default_index() {
|
||||
let bm1 = yield PlacesUtils.bookmarks.insert({ parentGuid: PlacesUtils.bookmarks.unfiledGuid,
|
||||
type: PlacesUtils.bookmarks.TYPE_BOOKMARK,
|
||||
url: "http://example.com/last",
|
||||
title: "last child" });
|
||||
checkBookmarkObject(bm1);
|
||||
|
||||
let bm2 = yield PlacesUtils.bookmarks.fetch({ parentGuid: bm1.parentGuid,
|
||||
index: PlacesUtils.bookmarks.DEFAULT_INDEX },
|
||||
gAccumulator.callback);
|
||||
checkBookmarkObject(bm2);
|
||||
Assert.equal(gAccumulator.results.length, 1);
|
||||
checkBookmarkObject(gAccumulator.results[0]);
|
||||
Assert.deepEqual(gAccumulator.results[0], bm1);
|
||||
|
||||
Assert.deepEqual(bm1, bm2);
|
||||
Assert.equal(bm2.parentGuid, PlacesUtils.bookmarks.unfiledGuid);
|
||||
Assert.equal(bm2.index, 1);
|
||||
Assert.deepEqual(bm2.dateAdded, bm2.lastModified);
|
||||
Assert.equal(bm2.type, PlacesUtils.bookmarks.TYPE_BOOKMARK);
|
||||
Assert.equal(bm2.url.href, "http://example.com/last");
|
||||
Assert.equal(bm2.title, "last child");
|
||||
|
||||
yield PlacesUtils.bookmarks.remove(bm1.guid);
|
||||
});
|
||||
|
||||
add_task(function* fetch_byurl_nonexisting() {
|
||||
let bm = yield PlacesUtils.bookmarks.fetch({ url: "http://nonexisting.com/" },
|
||||
gAccumulator.callback);
|
||||
Assert.equal(bm, null);
|
||||
Assert.equal(gAccumulator.results.length, 0);
|
||||
});
|
||||
|
||||
add_task(function* fetch_byurl() {
|
||||
let bm1 = yield PlacesUtils.bookmarks.insert({ parentGuid: PlacesUtils.bookmarks.unfiledGuid,
|
||||
type: PlacesUtils.bookmarks.TYPE_BOOKMARK,
|
||||
url: "http://byurl.com/",
|
||||
title: "a bookmark" });
|
||||
checkBookmarkObject(bm1);
|
||||
|
||||
// Also ensure that fecth-by-url excludes the tags folder.
|
||||
PlacesUtils.tagging.tagURI(uri(bm1.url.href), ["Test Tag"]);
|
||||
|
||||
let bm2 = yield PlacesUtils.bookmarks.fetch({ url: bm1.url },
|
||||
gAccumulator.callback);
|
||||
checkBookmarkObject(bm2);
|
||||
Assert.equal(gAccumulator.results.length, 1);
|
||||
checkBookmarkObject(gAccumulator.results[0]);
|
||||
Assert.deepEqual(gAccumulator.results[0], bm1);
|
||||
|
||||
Assert.deepEqual(bm1, bm2);
|
||||
Assert.equal(bm2.parentGuid, PlacesUtils.bookmarks.unfiledGuid);
|
||||
Assert.deepEqual(bm2.dateAdded, bm2.lastModified);
|
||||
Assert.equal(bm2.type, PlacesUtils.bookmarks.TYPE_BOOKMARK);
|
||||
Assert.equal(bm2.url.href, "http://byurl.com/");
|
||||
Assert.equal(bm2.title, "a bookmark");
|
||||
|
||||
let bm3 = yield PlacesUtils.bookmarks.insert({ parentGuid: PlacesUtils.bookmarks.unfiledGuid,
|
||||
type: PlacesUtils.bookmarks.TYPE_BOOKMARK,
|
||||
url: "http://byurl.com/",
|
||||
title: "a bookmark" });
|
||||
let bm4 = yield PlacesUtils.bookmarks.fetch({ url: bm1.url },
|
||||
gAccumulator.callback);
|
||||
checkBookmarkObject(bm4);
|
||||
Assert.deepEqual(bm3, bm4);
|
||||
Assert.equal(gAccumulator.results.length, 2);
|
||||
gAccumulator.results.forEach(checkBookmarkObject);
|
||||
Assert.deepEqual(gAccumulator.results[0], bm4);
|
||||
|
||||
// After an update the returned bookmark should change.
|
||||
yield PlacesUtils.bookmarks.update({ guid: bm1.guid, title: "new title" });
|
||||
let bm5 = yield PlacesUtils.bookmarks.fetch({ url: bm1.url },
|
||||
gAccumulator.callback);
|
||||
checkBookmarkObject(bm5);
|
||||
// Cannot use deepEqual cause lastModified changed.
|
||||
Assert.equal(bm1.guid, bm5.guid);
|
||||
Assert.ok(bm5.lastModified > bm1.lastModified);
|
||||
Assert.equal(gAccumulator.results.length, 2);
|
||||
gAccumulator.results.forEach(checkBookmarkObject);
|
||||
Assert.deepEqual(gAccumulator.results[0], bm5);
|
||||
|
||||
// cleanup
|
||||
PlacesUtils.tagging.untagURI(uri(bm1.url.href), ["Test Tag"]);
|
||||
});
|
||||
|
||||
function run_test() {
|
||||
run_next_test();
|
||||
}
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
add_task(function* invalid_input_throws() {
|
||||
Assert.throws(() => PlacesUtils.bookmarks.getRecent(),
|
||||
/numberOfItems argument is required/);
|
||||
Assert.throws(() => PlacesUtils.bookmarks.getRecent("abc"),
|
||||
/numberOfItems argument must be an integer/);
|
||||
Assert.throws(() => PlacesUtils.bookmarks.getRecent(1.2),
|
||||
/numberOfItems argument must be an integer/);
|
||||
Assert.throws(() => PlacesUtils.bookmarks.getRecent(0),
|
||||
/numberOfItems argument must be greater than zero/);
|
||||
Assert.throws(() => PlacesUtils.bookmarks.getRecent(-1),
|
||||
/numberOfItems argument must be greater than zero/);
|
||||
});
|
||||
|
||||
add_task(function* getRecent_returns_recent_bookmarks() {
|
||||
yield PlacesUtils.bookmarks.eraseEverything();
|
||||
|
||||
let bm1 = yield PlacesUtils.bookmarks.insert({ parentGuid: PlacesUtils.bookmarks.unfiledGuid,
|
||||
url: "http://example.com/",
|
||||
title: "a bookmark" });
|
||||
let bm2 = yield PlacesUtils.bookmarks.insert({ parentGuid: PlacesUtils.bookmarks.unfiledGuid,
|
||||
url: "http://example.org/path",
|
||||
title: "another bookmark" });
|
||||
let bm3 = yield PlacesUtils.bookmarks.insert({ parentGuid: PlacesUtils.bookmarks.unfiledGuid,
|
||||
url: "http://example.net/",
|
||||
title: "another bookmark" });
|
||||
let bm4 = yield PlacesUtils.bookmarks.insert({ parentGuid: PlacesUtils.bookmarks.unfiledGuid,
|
||||
url: "http://example.net/path",
|
||||
title: "yet another bookmark" });
|
||||
checkBookmarkObject(bm1);
|
||||
checkBookmarkObject(bm2);
|
||||
checkBookmarkObject(bm3);
|
||||
checkBookmarkObject(bm4);
|
||||
|
||||
let results = yield PlacesUtils.bookmarks.getRecent(3);
|
||||
Assert.equal(results.length, 3);
|
||||
checkBookmarkObject(results[0]);
|
||||
Assert.deepEqual(bm4, results[0]);
|
||||
checkBookmarkObject(results[1]);
|
||||
Assert.deepEqual(bm3, results[1]);
|
||||
checkBookmarkObject(results[2]);
|
||||
Assert.deepEqual(bm2, results[2]);
|
||||
|
||||
yield PlacesUtils.bookmarks.eraseEverything();
|
||||
});
|
||||
|
|
@ -0,0 +1,264 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
add_task(function* invalid_input_throws() {
|
||||
Assert.throws(() => PlacesUtils.bookmarks.insert(),
|
||||
/Input should be a valid object/);
|
||||
Assert.throws(() => PlacesUtils.bookmarks.insert(null),
|
||||
/Input should be a valid object/);
|
||||
Assert.throws(() => PlacesUtils.bookmarks.insert({}),
|
||||
/The following properties were expected/);
|
||||
|
||||
Assert.throws(() => PlacesUtils.bookmarks.insert({ guid: "test" }),
|
||||
/Invalid value for property 'guid'/);
|
||||
Assert.throws(() => PlacesUtils.bookmarks.insert({ guid: null }),
|
||||
/Invalid value for property 'guid'/);
|
||||
Assert.throws(() => PlacesUtils.bookmarks.insert({ guid: 123 }),
|
||||
/Invalid value for property 'guid'/);
|
||||
|
||||
Assert.throws(() => PlacesUtils.bookmarks.insert({ parentGuid: "test" }),
|
||||
/Invalid value for property 'parentGuid'/);
|
||||
Assert.throws(() => PlacesUtils.bookmarks.insert({ parentGuid: null }),
|
||||
/Invalid value for property 'parentGuid'/);
|
||||
Assert.throws(() => PlacesUtils.bookmarks.insert({ parentGuid: 123 }),
|
||||
/Invalid value for property 'parentGuid'/);
|
||||
|
||||
Assert.throws(() => PlacesUtils.bookmarks.insert({ index: "1" }),
|
||||
/Invalid value for property 'index'/);
|
||||
Assert.throws(() => PlacesUtils.bookmarks.insert({ index: -10 }),
|
||||
/Invalid value for property 'index'/);
|
||||
|
||||
Assert.throws(() => PlacesUtils.bookmarks.insert({ dateAdded: -10 }),
|
||||
/Invalid value for property 'dateAdded'/);
|
||||
Assert.throws(() => PlacesUtils.bookmarks.insert({ dateAdded: "today" }),
|
||||
/Invalid value for property 'dateAdded'/);
|
||||
Assert.throws(() => PlacesUtils.bookmarks.insert({ dateAdded: Date.now() }),
|
||||
/Invalid value for property 'dateAdded'/);
|
||||
|
||||
Assert.throws(() => PlacesUtils.bookmarks.insert({ lastModified: -10 }),
|
||||
/Invalid value for property 'lastModified'/);
|
||||
Assert.throws(() => PlacesUtils.bookmarks.insert({ lastModified: "today" }),
|
||||
/Invalid value for property 'lastModified'/);
|
||||
Assert.throws(() => PlacesUtils.bookmarks.insert({ lastModified: Date.now() }),
|
||||
/Invalid value for property 'lastModified'/);
|
||||
let time = new Date();
|
||||
let future = new Date(time + 86400000);
|
||||
Assert.throws(() => PlacesUtils.bookmarks.insert({ dateAdded: future,
|
||||
lastModified: time }),
|
||||
/Invalid value for property 'dateAdded'/);
|
||||
let past = new Date(time - 86400000);
|
||||
Assert.throws(() => PlacesUtils.bookmarks.insert({ lastModified: past }),
|
||||
/Invalid value for property 'lastModified'/);
|
||||
|
||||
Assert.throws(() => PlacesUtils.bookmarks.insert({ type: -1 }),
|
||||
/Invalid value for property 'type'/);
|
||||
Assert.throws(() => PlacesUtils.bookmarks.insert({ type: 100 }),
|
||||
/Invalid value for property 'type'/);
|
||||
Assert.throws(() => PlacesUtils.bookmarks.insert({ type: "bookmark" }),
|
||||
/Invalid value for property 'type'/);
|
||||
|
||||
Assert.throws(() => PlacesUtils.bookmarks.insert({ type: PlacesUtils.bookmarks.TYPE_BOOKMARK,
|
||||
title: -1 }),
|
||||
/Invalid value for property 'title'/);
|
||||
|
||||
Assert.throws(() => PlacesUtils.bookmarks.insert({ type: PlacesUtils.bookmarks.TYPE_BOOKMARK,
|
||||
url: 10 }),
|
||||
/Invalid value for property 'url'/);
|
||||
Assert.throws(() => PlacesUtils.bookmarks.insert({ type: PlacesUtils.bookmarks.TYPE_BOOKMARK,
|
||||
url: "http://te st" }),
|
||||
/Invalid value for property 'url'/);
|
||||
let longurl = "http://www.example.com/";
|
||||
for (let i = 0; i < 65536; i++) {
|
||||
longurl += "a";
|
||||
}
|
||||
Assert.throws(() => PlacesUtils.bookmarks.insert({ type: PlacesUtils.bookmarks.TYPE_BOOKMARK,
|
||||
url: longurl }),
|
||||
/Invalid value for property 'url'/);
|
||||
Assert.throws(() => PlacesUtils.bookmarks.insert({ type: PlacesUtils.bookmarks.TYPE_BOOKMARK,
|
||||
url: NetUtil.newURI(longurl) }),
|
||||
/Invalid value for property 'url'/);
|
||||
Assert.throws(() => PlacesUtils.bookmarks.insert({ type: PlacesUtils.bookmarks.TYPE_BOOKMARK,
|
||||
url: "te st" }),
|
||||
/Invalid value for property 'url'/);
|
||||
});
|
||||
|
||||
add_task(function* invalid_properties_for_bookmark_type() {
|
||||
Assert.throws(() => PlacesUtils.bookmarks.insert({ type: PlacesUtils.bookmarks.TYPE_FOLDER,
|
||||
url: "http://www.moz.com/" }),
|
||||
/Invalid value for property 'url'/);
|
||||
Assert.throws(() => PlacesUtils.bookmarks.insert({ type: PlacesUtils.bookmarks.TYPE_SEPARATOR,
|
||||
url: "http://www.moz.com/" }),
|
||||
/Invalid value for property 'url'/);
|
||||
Assert.throws(() => PlacesUtils.bookmarks.insert({ type: PlacesUtils.bookmarks.TYPE_SEPARATOR,
|
||||
title: "test" }),
|
||||
/Invalid value for property 'title'/);
|
||||
});
|
||||
|
||||
add_task(function* long_title_trim() {
|
||||
let longtitle = "a";
|
||||
for (let i = 0; i < 4096; i++) {
|
||||
longtitle += "a";
|
||||
}
|
||||
let bm = yield PlacesUtils.bookmarks.insert({ parentGuid: PlacesUtils.bookmarks.unfiledGuid,
|
||||
type: PlacesUtils.bookmarks.TYPE_FOLDER,
|
||||
title: longtitle });
|
||||
checkBookmarkObject(bm);
|
||||
Assert.equal(bm.parentGuid, PlacesUtils.bookmarks.unfiledGuid);
|
||||
Assert.equal(bm.index, 0);
|
||||
Assert.equal(bm.dateAdded, bm.lastModified);
|
||||
Assert.equal(bm.type, PlacesUtils.bookmarks.TYPE_FOLDER);
|
||||
Assert.equal(bm.title.length, 4096, "title should have been trimmed");
|
||||
Assert.ok(!("url" in bm), "url should not be set");
|
||||
});
|
||||
|
||||
add_task(function* create_separator() {
|
||||
let bm = yield PlacesUtils.bookmarks.insert({ parentGuid: PlacesUtils.bookmarks.unfiledGuid,
|
||||
type: PlacesUtils.bookmarks.TYPE_SEPARATOR,
|
||||
index: PlacesUtils.bookmarks.DEFAULT_INDEX });
|
||||
checkBookmarkObject(bm);
|
||||
Assert.equal(bm.parentGuid, PlacesUtils.bookmarks.unfiledGuid);
|
||||
Assert.equal(bm.index, 1);
|
||||
Assert.equal(bm.dateAdded, bm.lastModified);
|
||||
Assert.equal(bm.type, PlacesUtils.bookmarks.TYPE_SEPARATOR);
|
||||
Assert.ok(!("title" in bm), "title should not be set");
|
||||
});
|
||||
|
||||
add_task(function* create_separator_w_title_fail() {
|
||||
try {
|
||||
yield PlacesUtils.bookmarks.insert({ parentGuid: PlacesUtils.bookmarks.unfiledGuid,
|
||||
type: PlacesUtils.bookmarks.TYPE_SEPARATOR,
|
||||
title: "a separator" });
|
||||
Assert.ok(false, "Trying to set title for a separator should reject");
|
||||
} catch (ex) {}
|
||||
});
|
||||
|
||||
add_task(function* create_separator_invalid_parent_fail() {
|
||||
try {
|
||||
yield PlacesUtils.bookmarks.insert({ parentGuid: "123456789012",
|
||||
type: PlacesUtils.bookmarks.TYPE_SEPARATOR,
|
||||
title: "a separator" });
|
||||
Assert.ok(false, "Trying to create an item in a non existing parent reject");
|
||||
} catch (ex) {}
|
||||
});
|
||||
|
||||
add_task(function* create_separator_given_guid() {
|
||||
let bm = yield PlacesUtils.bookmarks.insert({ parentGuid: PlacesUtils.bookmarks.unfiledGuid,
|
||||
type: PlacesUtils.bookmarks.TYPE_SEPARATOR,
|
||||
index: PlacesUtils.bookmarks.DEFAULT_INDEX,
|
||||
guid: "123456789012" });
|
||||
checkBookmarkObject(bm);
|
||||
Assert.equal(bm.guid, "123456789012");
|
||||
Assert.equal(bm.parentGuid, PlacesUtils.bookmarks.unfiledGuid);
|
||||
Assert.equal(bm.index, 2);
|
||||
Assert.equal(bm.dateAdded, bm.lastModified);
|
||||
Assert.equal(bm.type, PlacesUtils.bookmarks.TYPE_SEPARATOR);
|
||||
Assert.ok(!("title" in bm), "title should not be set");
|
||||
});
|
||||
|
||||
add_task(function* create_item_given_guid_no_type_fail() {
|
||||
try {
|
||||
yield PlacesUtils.bookmarks.insert({ parentGuid: "123456789012" });
|
||||
Assert.ok(false, "Trying to create an item with a given guid but no type should reject");
|
||||
} catch (ex) {}
|
||||
});
|
||||
|
||||
add_task(function* create_separator_big_index() {
|
||||
let bm = yield PlacesUtils.bookmarks.insert({ parentGuid: PlacesUtils.bookmarks.unfiledGuid,
|
||||
type: PlacesUtils.bookmarks.TYPE_SEPARATOR,
|
||||
index: 9999 });
|
||||
checkBookmarkObject(bm);
|
||||
Assert.equal(bm.parentGuid, PlacesUtils.bookmarks.unfiledGuid);
|
||||
Assert.equal(bm.index, 3);
|
||||
Assert.equal(bm.dateAdded, bm.lastModified);
|
||||
Assert.equal(bm.type, PlacesUtils.bookmarks.TYPE_SEPARATOR);
|
||||
Assert.ok(!("title" in bm), "title should not be set");
|
||||
});
|
||||
|
||||
add_task(function* create_separator_given_dateAdded() {
|
||||
let time = new Date();
|
||||
let past = new Date(time - 86400000);
|
||||
let bm = yield PlacesUtils.bookmarks.insert({ parentGuid: PlacesUtils.bookmarks.unfiledGuid,
|
||||
type: PlacesUtils.bookmarks.TYPE_SEPARATOR,
|
||||
dateAdded: past });
|
||||
checkBookmarkObject(bm);
|
||||
Assert.equal(bm.dateAdded, past);
|
||||
Assert.equal(bm.lastModified, past);
|
||||
});
|
||||
|
||||
add_task(function* create_folder() {
|
||||
let bm = yield PlacesUtils.bookmarks.insert({ parentGuid: PlacesUtils.bookmarks.unfiledGuid,
|
||||
type: PlacesUtils.bookmarks.TYPE_FOLDER });
|
||||
checkBookmarkObject(bm);
|
||||
Assert.equal(bm.parentGuid, PlacesUtils.bookmarks.unfiledGuid);
|
||||
Assert.equal(bm.dateAdded, bm.lastModified);
|
||||
Assert.equal(bm.type, PlacesUtils.bookmarks.TYPE_FOLDER);
|
||||
Assert.ok(!("title" in bm), "title should not be set");
|
||||
|
||||
// And then create a nested folder.
|
||||
let parentGuid = bm.guid;
|
||||
bm = yield PlacesUtils.bookmarks.insert({ parentGuid: parentGuid,
|
||||
type: PlacesUtils.bookmarks.TYPE_FOLDER,
|
||||
title: "a folder" });
|
||||
checkBookmarkObject(bm);
|
||||
Assert.equal(bm.parentGuid, parentGuid);
|
||||
Assert.equal(bm.index, 0);
|
||||
Assert.equal(bm.type, PlacesUtils.bookmarks.TYPE_FOLDER);
|
||||
Assert.strictEqual(bm.title, "a folder");
|
||||
});
|
||||
|
||||
add_task(function* create_bookmark() {
|
||||
let bm = yield PlacesUtils.bookmarks.insert({ parentGuid: PlacesUtils.bookmarks.unfiledGuid,
|
||||
type: PlacesUtils.bookmarks.TYPE_FOLDER });
|
||||
let parentGuid = bm.guid;
|
||||
|
||||
bm = yield PlacesUtils.bookmarks.insert({ parentGuid: parentGuid,
|
||||
type: PlacesUtils.bookmarks.TYPE_BOOKMARK,
|
||||
url: "http://example.com/",
|
||||
title: "a bookmark" });
|
||||
checkBookmarkObject(bm);
|
||||
Assert.equal(bm.parentGuid, parentGuid);
|
||||
Assert.equal(bm.index, 0);
|
||||
Assert.equal(bm.type, PlacesUtils.bookmarks.TYPE_BOOKMARK);
|
||||
Assert.equal(bm.url.href, "http://example.com/");
|
||||
Assert.equal(bm.title, "a bookmark");
|
||||
|
||||
// Check parent lastModified.
|
||||
let parent = yield PlacesUtils.bookmarks.fetch({ guid: bm.parentGuid });
|
||||
Assert.deepEqual(parent.lastModified, bm.dateAdded);
|
||||
|
||||
bm = yield PlacesUtils.bookmarks.insert({ parentGuid: parentGuid,
|
||||
type: PlacesUtils.bookmarks.TYPE_BOOKMARK,
|
||||
url: new URL("http://example.com/") });
|
||||
checkBookmarkObject(bm);
|
||||
Assert.equal(bm.parentGuid, parentGuid);
|
||||
Assert.equal(bm.index, 1);
|
||||
Assert.equal(bm.type, PlacesUtils.bookmarks.TYPE_BOOKMARK);
|
||||
Assert.equal(bm.url.href, "http://example.com/");
|
||||
Assert.ok(!("title" in bm), "title should not be set");
|
||||
});
|
||||
|
||||
add_task(function* create_bookmark_frecency() {
|
||||
let bm = yield PlacesUtils.bookmarks.insert({ parentGuid: PlacesUtils.bookmarks.unfiledGuid,
|
||||
type: PlacesUtils.bookmarks.TYPE_BOOKMARK,
|
||||
url: "http://example.com/",
|
||||
title: "a bookmark" });
|
||||
checkBookmarkObject(bm);
|
||||
|
||||
yield PlacesTestUtils.promiseAsyncUpdates();
|
||||
Assert.ok(frecencyForUrl(bm.url) > 0, "Check frecency has been updated")
|
||||
});
|
||||
|
||||
add_task(function* create_bookmark_without_type() {
|
||||
let bm = yield PlacesUtils.bookmarks.insert({ parentGuid: PlacesUtils.bookmarks.unfiledGuid,
|
||||
url: "http://example.com/",
|
||||
title: "a bookmark" });
|
||||
checkBookmarkObject(bm);
|
||||
Assert.equal(bm.parentGuid, PlacesUtils.bookmarks.unfiledGuid);
|
||||
Assert.equal(bm.type, PlacesUtils.bookmarks.TYPE_BOOKMARK);
|
||||
Assert.equal(bm.url.href, "http://example.com/");
|
||||
Assert.equal(bm.title, "a bookmark");
|
||||
});
|
||||
|
||||
function run_test() {
|
||||
run_next_test();
|
||||
}
|
||||
|
|
@ -0,0 +1,527 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
add_task(function* insert_separator_notification() {
|
||||
let observer = expectNotifications();
|
||||
let bm = yield PlacesUtils.bookmarks.insert({ type: PlacesUtils.bookmarks.TYPE_SEPARATOR,
|
||||
parentGuid: PlacesUtils.bookmarks.unfiledGuid});
|
||||
let itemId = yield PlacesUtils.promiseItemId(bm.guid);
|
||||
let parentId = yield PlacesUtils.promiseItemId(bm.parentGuid);
|
||||
observer.check([ { name: "onItemAdded",
|
||||
arguments: [ itemId, parentId, bm.index, bm.type,
|
||||
null, null, bm.dateAdded,
|
||||
bm.guid, bm.parentGuid,
|
||||
Ci.nsINavBookmarksService.SOURCE_DEFAULT ] }
|
||||
]);
|
||||
});
|
||||
|
||||
add_task(function* insert_folder_notification() {
|
||||
let observer = expectNotifications();
|
||||
let bm = yield PlacesUtils.bookmarks.insert({ type: PlacesUtils.bookmarks.TYPE_FOLDER,
|
||||
parentGuid: PlacesUtils.bookmarks.unfiledGuid,
|
||||
title: "a folder" });
|
||||
let itemId = yield PlacesUtils.promiseItemId(bm.guid);
|
||||
let parentId = yield PlacesUtils.promiseItemId(bm.parentGuid);
|
||||
observer.check([ { name: "onItemAdded",
|
||||
arguments: [ itemId, parentId, bm.index, bm.type,
|
||||
null, bm.title, bm.dateAdded,
|
||||
bm.guid, bm.parentGuid,
|
||||
Ci.nsINavBookmarksService.SOURCE_DEFAULT ] }
|
||||
]);
|
||||
});
|
||||
|
||||
add_task(function* insert_folder_notitle_notification() {
|
||||
let observer = expectNotifications();
|
||||
let bm = yield PlacesUtils.bookmarks.insert({ type: PlacesUtils.bookmarks.TYPE_FOLDER,
|
||||
parentGuid: PlacesUtils.bookmarks.unfiledGuid });
|
||||
let itemId = yield PlacesUtils.promiseItemId(bm.guid);
|
||||
let parentId = yield PlacesUtils.promiseItemId(bm.parentGuid);
|
||||
observer.check([ { name: "onItemAdded",
|
||||
arguments: [ itemId, parentId, bm.index, bm.type,
|
||||
null, null, bm.dateAdded,
|
||||
bm.guid, bm.parentGuid,
|
||||
Ci.nsINavBookmarksService.SOURCE_DEFAULT ] }
|
||||
]);
|
||||
});
|
||||
|
||||
add_task(function* insert_bookmark_notification() {
|
||||
let observer = expectNotifications();
|
||||
let bm = yield PlacesUtils.bookmarks.insert({ type: PlacesUtils.bookmarks.TYPE_BOOKMARK,
|
||||
parentGuid: PlacesUtils.bookmarks.unfiledGuid,
|
||||
url: new URL("http://example.com/"),
|
||||
title: "a bookmark" });
|
||||
let itemId = yield PlacesUtils.promiseItemId(bm.guid);
|
||||
let parentId = yield PlacesUtils.promiseItemId(bm.parentGuid);
|
||||
observer.check([ { name: "onItemAdded",
|
||||
arguments: [ itemId, parentId, bm.index, bm.type,
|
||||
bm.url, bm.title, bm.dateAdded,
|
||||
bm.guid, bm.parentGuid,
|
||||
Ci.nsINavBookmarksService.SOURCE_DEFAULT ] }
|
||||
]);
|
||||
});
|
||||
|
||||
add_task(function* insert_bookmark_notitle_notification() {
|
||||
let observer = expectNotifications();
|
||||
let bm = yield PlacesUtils.bookmarks.insert({ type: PlacesUtils.bookmarks.TYPE_BOOKMARK,
|
||||
parentGuid: PlacesUtils.bookmarks.unfiledGuid,
|
||||
url: new URL("http://example.com/") });
|
||||
let itemId = yield PlacesUtils.promiseItemId(bm.guid);
|
||||
let parentId = yield PlacesUtils.promiseItemId(bm.parentGuid);
|
||||
observer.check([ { name: "onItemAdded",
|
||||
arguments: [ itemId, parentId, bm.index, bm.type,
|
||||
bm.url, null, bm.dateAdded,
|
||||
bm.guid, bm.parentGuid,
|
||||
Ci.nsINavBookmarksService.SOURCE_DEFAULT ] }
|
||||
]);
|
||||
});
|
||||
|
||||
add_task(function* insert_bookmark_tag_notification() {
|
||||
let bm = yield PlacesUtils.bookmarks.insert({ type: PlacesUtils.bookmarks.TYPE_BOOKMARK,
|
||||
parentGuid: PlacesUtils.bookmarks.unfiledGuid,
|
||||
url: new URL("http://tag.example.com/") });
|
||||
let itemId = yield PlacesUtils.promiseItemId(bm.guid);
|
||||
let parentId = yield PlacesUtils.promiseItemId(bm.parentGuid);
|
||||
|
||||
let tagFolder = yield PlacesUtils.bookmarks.insert({ type: PlacesUtils.bookmarks.TYPE_FOLDER,
|
||||
parentGuid: PlacesUtils.bookmarks.tagsGuid,
|
||||
title: "tag" });
|
||||
let observer = expectNotifications();
|
||||
let tag = yield PlacesUtils.bookmarks.insert({ type: PlacesUtils.bookmarks.TYPE_BOOKMARK,
|
||||
parentGuid: tagFolder.guid,
|
||||
url: new URL("http://tag.example.com/") });
|
||||
let tagId = yield PlacesUtils.promiseItemId(tag.guid);
|
||||
let tagParentId = yield PlacesUtils.promiseItemId(tag.parentGuid);
|
||||
|
||||
observer.check([ { name: "onItemAdded",
|
||||
arguments: [ tagId, tagParentId, tag.index, tag.type,
|
||||
tag.url, null, tag.dateAdded,
|
||||
tag.guid, tag.parentGuid,
|
||||
Ci.nsINavBookmarksService.SOURCE_DEFAULT ] },
|
||||
{ name: "onItemChanged",
|
||||
arguments: [ itemId, "tags", false, "",
|
||||
bm.lastModified, bm.type, parentId,
|
||||
bm.guid, bm.parentGuid, "",
|
||||
Ci.nsINavBookmarksService.SOURCE_DEFAULT ] }
|
||||
]);
|
||||
});
|
||||
|
||||
add_task(function* update_bookmark_lastModified() {
|
||||
let bm = yield PlacesUtils.bookmarks.insert({ type: PlacesUtils.bookmarks.TYPE_BOOKMARK,
|
||||
parentGuid: PlacesUtils.bookmarks.unfiledGuid,
|
||||
url: new URL("http://lastmod.example.com/") });
|
||||
let observer = expectNotifications();
|
||||
bm = yield PlacesUtils.bookmarks.update({ guid: bm.guid,
|
||||
lastModified: new Date() });
|
||||
let itemId = yield PlacesUtils.promiseItemId(bm.guid);
|
||||
let parentId = yield PlacesUtils.promiseItemId(bm.parentGuid);
|
||||
|
||||
observer.check([ { name: "onItemChanged",
|
||||
arguments: [ itemId, "lastModified", false,
|
||||
`${bm.lastModified * 1000}`, bm.lastModified,
|
||||
bm.type, parentId, bm.guid, bm.parentGuid, "",
|
||||
Ci.nsINavBookmarksService.SOURCE_DEFAULT ] }
|
||||
]);
|
||||
});
|
||||
|
||||
add_task(function* update_bookmark_title() {
|
||||
let bm = yield PlacesUtils.bookmarks.insert({ type: PlacesUtils.bookmarks.TYPE_BOOKMARK,
|
||||
parentGuid: PlacesUtils.bookmarks.unfiledGuid,
|
||||
url: new URL("http://title.example.com/") });
|
||||
let observer = expectNotifications();
|
||||
bm = yield PlacesUtils.bookmarks.update({ guid: bm.guid,
|
||||
title: "new title" });
|
||||
let itemId = yield PlacesUtils.promiseItemId(bm.guid);
|
||||
let parentId = yield PlacesUtils.promiseItemId(bm.parentGuid);
|
||||
|
||||
observer.check([ { name: "onItemChanged",
|
||||
arguments: [ itemId, "title", false, bm.title,
|
||||
bm.lastModified, bm.type, parentId, bm.guid,
|
||||
bm.parentGuid, "", Ci.nsINavBookmarksService.SOURCE_DEFAULT ] }
|
||||
]);
|
||||
});
|
||||
|
||||
add_task(function* update_bookmark_uri() {
|
||||
let bm = yield PlacesUtils.bookmarks.insert({ type: PlacesUtils.bookmarks.TYPE_BOOKMARK,
|
||||
parentGuid: PlacesUtils.bookmarks.unfiledGuid,
|
||||
url: new URL("http://url.example.com/") });
|
||||
let observer = expectNotifications();
|
||||
bm = yield PlacesUtils.bookmarks.update({ guid: bm.guid,
|
||||
url: "http://mozilla.org/" });
|
||||
let itemId = yield PlacesUtils.promiseItemId(bm.guid);
|
||||
let parentId = yield PlacesUtils.promiseItemId(bm.parentGuid);
|
||||
|
||||
observer.check([ { name: "onItemChanged",
|
||||
arguments: [ itemId, "uri", false, bm.url.href,
|
||||
bm.lastModified, bm.type, parentId, bm.guid,
|
||||
bm.parentGuid, "http://url.example.com/",
|
||||
Ci.nsINavBookmarksService.SOURCE_DEFAULT ] }
|
||||
]);
|
||||
});
|
||||
|
||||
add_task(function* update_move_same_folder() {
|
||||
// Ensure there are at least two items in place (others test do so for us,
|
||||
// but we don't have to depend on that).
|
||||
yield PlacesUtils.bookmarks.insert({ type: PlacesUtils.bookmarks.TYPE_SEPARATOR,
|
||||
parentGuid: PlacesUtils.bookmarks.unfiledGuid });
|
||||
let bm = yield PlacesUtils.bookmarks.insert({ type: PlacesUtils.bookmarks.TYPE_BOOKMARK,
|
||||
parentGuid: PlacesUtils.bookmarks.unfiledGuid,
|
||||
url: new URL("http://move.example.com/") });
|
||||
let bmItemId = yield PlacesUtils.promiseItemId(bm.guid);
|
||||
let bmParentId = yield PlacesUtils.promiseItemId(bm.parentGuid);
|
||||
let bmOldIndex = bm.index;
|
||||
|
||||
let observer = expectNotifications();
|
||||
bm = yield PlacesUtils.bookmarks.update({ guid: bm.guid,
|
||||
parentGuid: PlacesUtils.bookmarks.unfiledGuid,
|
||||
index: 0 });
|
||||
Assert.equal(bm.index, 0);
|
||||
observer.check([ { name: "onItemMoved",
|
||||
arguments: [ bmItemId, bmParentId, bmOldIndex, bmParentId, bm.index,
|
||||
bm.type, bm.guid, bm.parentGuid, bm.parentGuid,
|
||||
Ci.nsINavBookmarksService.SOURCE_DEFAULT ] }
|
||||
]);
|
||||
|
||||
// Test that we get the right index for DEFAULT_INDEX input.
|
||||
bmOldIndex = 0;
|
||||
observer = expectNotifications();
|
||||
bm = yield PlacesUtils.bookmarks.update({ guid: bm.guid,
|
||||
parentGuid: PlacesUtils.bookmarks.unfiledGuid,
|
||||
index: PlacesUtils.bookmarks.DEFAULT_INDEX });
|
||||
Assert.ok(bm.index > 0);
|
||||
observer.check([ { name: "onItemMoved",
|
||||
arguments: [ bmItemId, bmParentId, bmOldIndex, bmParentId, bm.index,
|
||||
bm.type, bm.guid, bm.parentGuid, bm.parentGuid,
|
||||
Ci.nsINavBookmarksService.SOURCE_DEFAULT ] }
|
||||
]);
|
||||
});
|
||||
|
||||
add_task(function* update_move_different_folder() {
|
||||
let bm = yield PlacesUtils.bookmarks.insert({ type: PlacesUtils.bookmarks.TYPE_BOOKMARK,
|
||||
parentGuid: PlacesUtils.bookmarks.unfiledGuid,
|
||||
url: new URL("http://move.example.com/") });
|
||||
let folder = yield PlacesUtils.bookmarks.insert({ type: PlacesUtils.bookmarks.TYPE_FOLDER,
|
||||
parentGuid: PlacesUtils.bookmarks.unfiledGuid });
|
||||
let bmItemId = yield PlacesUtils.promiseItemId(bm.guid);
|
||||
let bmOldParentId = PlacesUtils.unfiledBookmarksFolderId;
|
||||
let bmOldIndex = bm.index;
|
||||
|
||||
let observer = expectNotifications();
|
||||
bm = yield PlacesUtils.bookmarks.update({ guid: bm.guid,
|
||||
parentGuid: folder.guid,
|
||||
index: PlacesUtils.bookmarks.DEFAULT_INDEX });
|
||||
Assert.equal(bm.index, 0);
|
||||
let bmNewParentId = yield PlacesUtils.promiseItemId(folder.guid);
|
||||
observer.check([ { name: "onItemMoved",
|
||||
arguments: [ bmItemId, bmOldParentId, bmOldIndex, bmNewParentId,
|
||||
bm.index, bm.type, bm.guid,
|
||||
PlacesUtils.bookmarks.unfiledGuid,
|
||||
bm.parentGuid,
|
||||
Ci.nsINavBookmarksService.SOURCE_DEFAULT ] }
|
||||
]);
|
||||
});
|
||||
|
||||
add_task(function* remove_bookmark() {
|
||||
let bm = yield PlacesUtils.bookmarks.insert({ type: PlacesUtils.bookmarks.TYPE_BOOKMARK,
|
||||
parentGuid: PlacesUtils.bookmarks.unfiledGuid,
|
||||
url: new URL("http://remove.example.com/") });
|
||||
let itemId = yield PlacesUtils.promiseItemId(bm.guid);
|
||||
let parentId = yield PlacesUtils.promiseItemId(bm.parentGuid);
|
||||
|
||||
let observer = expectNotifications();
|
||||
bm = yield PlacesUtils.bookmarks.remove(bm.guid);
|
||||
// TODO (Bug 653910): onItemAnnotationRemoved notified even if there were no
|
||||
// annotations.
|
||||
observer.check([ { name: "onItemRemoved",
|
||||
arguments: [ itemId, parentId, bm.index, bm.type, bm.url,
|
||||
bm.guid, bm.parentGuid,
|
||||
Ci.nsINavBookmarksService.SOURCE_DEFAULT ] }
|
||||
]);
|
||||
});
|
||||
|
||||
add_task(function* remove_folder() {
|
||||
let bm = yield PlacesUtils.bookmarks.insert({ type: PlacesUtils.bookmarks.TYPE_FOLDER,
|
||||
parentGuid: PlacesUtils.bookmarks.unfiledGuid });
|
||||
let itemId = yield PlacesUtils.promiseItemId(bm.guid);
|
||||
let parentId = yield PlacesUtils.promiseItemId(bm.parentGuid);
|
||||
|
||||
let observer = expectNotifications();
|
||||
bm = yield PlacesUtils.bookmarks.remove(bm.guid);
|
||||
observer.check([ { name: "onItemRemoved",
|
||||
arguments: [ itemId, parentId, bm.index, bm.type, null,
|
||||
bm.guid, bm.parentGuid,
|
||||
Ci.nsINavBookmarksService.SOURCE_DEFAULT ] }
|
||||
]);
|
||||
});
|
||||
|
||||
add_task(function* remove_bookmark_tag_notification() {
|
||||
let bm = yield PlacesUtils.bookmarks.insert({ type: PlacesUtils.bookmarks.TYPE_BOOKMARK,
|
||||
parentGuid: PlacesUtils.bookmarks.unfiledGuid,
|
||||
url: new URL("http://untag.example.com/") });
|
||||
let itemId = yield PlacesUtils.promiseItemId(bm.guid);
|
||||
let parentId = yield PlacesUtils.promiseItemId(bm.parentGuid);
|
||||
|
||||
let tagFolder = yield PlacesUtils.bookmarks.insert({ type: PlacesUtils.bookmarks.TYPE_FOLDER,
|
||||
parentGuid: PlacesUtils.bookmarks.tagsGuid,
|
||||
title: "tag" });
|
||||
let tag = yield PlacesUtils.bookmarks.insert({ type: PlacesUtils.bookmarks.TYPE_BOOKMARK,
|
||||
parentGuid: tagFolder.guid,
|
||||
url: new URL("http://untag.example.com/") });
|
||||
let tagId = yield PlacesUtils.promiseItemId(tag.guid);
|
||||
let tagParentId = yield PlacesUtils.promiseItemId(tag.parentGuid);
|
||||
|
||||
let observer = expectNotifications();
|
||||
yield PlacesUtils.bookmarks.remove(tag.guid);
|
||||
|
||||
observer.check([ { name: "onItemRemoved",
|
||||
arguments: [ tagId, tagParentId, tag.index, tag.type,
|
||||
tag.url, tag.guid, tag.parentGuid,
|
||||
Ci.nsINavBookmarksService.SOURCE_DEFAULT ] },
|
||||
{ name: "onItemChanged",
|
||||
arguments: [ itemId, "tags", false, "",
|
||||
bm.lastModified, bm.type, parentId,
|
||||
bm.guid, bm.parentGuid, "",
|
||||
Ci.nsINavBookmarksService.SOURCE_DEFAULT ] }
|
||||
]);
|
||||
});
|
||||
|
||||
add_task(function* remove_folder_notification() {
|
||||
let folder1 = yield PlacesUtils.bookmarks.insert({ type: PlacesUtils.bookmarks.TYPE_FOLDER,
|
||||
parentGuid: PlacesUtils.bookmarks.unfiledGuid });
|
||||
let folder1Id = yield PlacesUtils.promiseItemId(folder1.guid);
|
||||
let folder1ParentId = yield PlacesUtils.promiseItemId(folder1.parentGuid);
|
||||
|
||||
let bm = yield PlacesUtils.bookmarks.insert({ type: PlacesUtils.bookmarks.TYPE_BOOKMARK,
|
||||
parentGuid: folder1.guid,
|
||||
url: new URL("http://example.com/") });
|
||||
let bmItemId = yield PlacesUtils.promiseItemId(bm.guid);
|
||||
|
||||
let folder2 = yield PlacesUtils.bookmarks.insert({ type: PlacesUtils.bookmarks.TYPE_FOLDER,
|
||||
parentGuid: folder1.guid });
|
||||
let folder2Id = yield PlacesUtils.promiseItemId(folder2.guid);
|
||||
|
||||
let bm2 = yield PlacesUtils.bookmarks.insert({ type: PlacesUtils.bookmarks.TYPE_BOOKMARK,
|
||||
parentGuid: folder2.guid,
|
||||
url: new URL("http://example.com/") });
|
||||
let bm2ItemId = yield PlacesUtils.promiseItemId(bm2.guid);
|
||||
|
||||
let observer = expectNotifications();
|
||||
yield PlacesUtils.bookmarks.remove(folder1.guid);
|
||||
|
||||
observer.check([ { name: "onItemRemoved",
|
||||
arguments: [ bm2ItemId, folder2Id, bm2.index, bm2.type,
|
||||
bm2.url, bm2.guid, bm2.parentGuid,
|
||||
Ci.nsINavBookmarksService.SOURCE_DEFAULT ] },
|
||||
{ name: "onItemRemoved",
|
||||
arguments: [ folder2Id, folder1Id, folder2.index,
|
||||
folder2.type, null, folder2.guid,
|
||||
folder2.parentGuid,
|
||||
Ci.nsINavBookmarksService.SOURCE_DEFAULT ] },
|
||||
{ name: "onItemRemoved",
|
||||
arguments: [ bmItemId, folder1Id, bm.index, bm.type,
|
||||
bm.url, bm.guid, bm.parentGuid,
|
||||
Ci.nsINavBookmarksService.SOURCE_DEFAULT ] },
|
||||
{ name: "onItemRemoved",
|
||||
arguments: [ folder1Id, folder1ParentId, folder1.index,
|
||||
folder1.type, null, folder1.guid,
|
||||
folder1.parentGuid,
|
||||
Ci.nsINavBookmarksService.SOURCE_DEFAULT ] }
|
||||
]);
|
||||
});
|
||||
|
||||
add_task(function* eraseEverything_notification() {
|
||||
// Let's start from a clean situation.
|
||||
yield PlacesUtils.bookmarks.eraseEverything();
|
||||
|
||||
let folder1 = yield PlacesUtils.bookmarks.insert({ type: PlacesUtils.bookmarks.TYPE_FOLDER,
|
||||
parentGuid: PlacesUtils.bookmarks.unfiledGuid });
|
||||
let folder1Id = yield PlacesUtils.promiseItemId(folder1.guid);
|
||||
let folder1ParentId = yield PlacesUtils.promiseItemId(folder1.parentGuid);
|
||||
|
||||
let bm = yield PlacesUtils.bookmarks.insert({ type: PlacesUtils.bookmarks.TYPE_BOOKMARK,
|
||||
parentGuid: folder1.guid,
|
||||
url: new URL("http://example.com/") });
|
||||
let itemId = yield PlacesUtils.promiseItemId(bm.guid);
|
||||
let parentId = yield PlacesUtils.promiseItemId(bm.parentGuid);
|
||||
|
||||
let folder2 = yield PlacesUtils.bookmarks.insert({ type: PlacesUtils.bookmarks.TYPE_FOLDER,
|
||||
parentGuid: PlacesUtils.bookmarks.unfiledGuid });
|
||||
let folder2Id = yield PlacesUtils.promiseItemId(folder2.guid);
|
||||
let folder2ParentId = yield PlacesUtils.promiseItemId(folder2.parentGuid);
|
||||
|
||||
let toolbarBm = yield PlacesUtils.bookmarks.insert({ type: PlacesUtils.bookmarks.TYPE_BOOKMARK,
|
||||
parentGuid: PlacesUtils.bookmarks.toolbarGuid,
|
||||
url: new URL("http://example.com/") });
|
||||
let toolbarBmId = yield PlacesUtils.promiseItemId(toolbarBm.guid);
|
||||
let toolbarBmParentId = yield PlacesUtils.promiseItemId(toolbarBm.parentGuid);
|
||||
|
||||
let menuBm = yield PlacesUtils.bookmarks.insert({ type: PlacesUtils.bookmarks.TYPE_BOOKMARK,
|
||||
parentGuid: PlacesUtils.bookmarks.menuGuid,
|
||||
url: new URL("http://example.com/") });
|
||||
let menuBmId = yield PlacesUtils.promiseItemId(menuBm.guid);
|
||||
let menuBmParentId = yield PlacesUtils.promiseItemId(menuBm.parentGuid);
|
||||
|
||||
let observer = expectNotifications();
|
||||
yield PlacesUtils.bookmarks.eraseEverything();
|
||||
|
||||
// Bookmarks should always be notified before their parents.
|
||||
observer.check([ { name: "onItemRemoved",
|
||||
arguments: [ itemId, parentId, bm.index, bm.type,
|
||||
bm.url, bm.guid, bm.parentGuid,
|
||||
Ci.nsINavBookmarksService.SOURCE_DEFAULT ] },
|
||||
{ name: "onItemRemoved",
|
||||
arguments: [ folder2Id, folder2ParentId, folder2.index,
|
||||
folder2.type, null, folder2.guid,
|
||||
folder2.parentGuid,
|
||||
Ci.nsINavBookmarksService.SOURCE_DEFAULT ] },
|
||||
{ name: "onItemRemoved",
|
||||
arguments: [ folder1Id, folder1ParentId, folder1.index,
|
||||
folder1.type, null, folder1.guid,
|
||||
folder1.parentGuid,
|
||||
Ci.nsINavBookmarksService.SOURCE_DEFAULT ] },
|
||||
{ name: "onItemRemoved",
|
||||
arguments: [ menuBmId, menuBmParentId,
|
||||
menuBm.index, menuBm.type,
|
||||
menuBm.url, menuBm.guid,
|
||||
menuBm.parentGuid,
|
||||
Ci.nsINavBookmarksService.SOURCE_DEFAULT ] },
|
||||
{ name: "onItemRemoved",
|
||||
arguments: [ toolbarBmId, toolbarBmParentId,
|
||||
toolbarBm.index, toolbarBm.type,
|
||||
toolbarBm.url, toolbarBm.guid,
|
||||
toolbarBm.parentGuid,
|
||||
Ci.nsINavBookmarksService.SOURCE_DEFAULT ] },
|
||||
]);
|
||||
});
|
||||
|
||||
add_task(function* eraseEverything_reparented_notification() {
|
||||
// Let's start from a clean situation.
|
||||
yield PlacesUtils.bookmarks.eraseEverything();
|
||||
|
||||
let folder1 = yield PlacesUtils.bookmarks.insert({ type: PlacesUtils.bookmarks.TYPE_FOLDER,
|
||||
parentGuid: PlacesUtils.bookmarks.unfiledGuid });
|
||||
let folder1Id = yield PlacesUtils.promiseItemId(folder1.guid);
|
||||
let folder1ParentId = yield PlacesUtils.promiseItemId(folder1.parentGuid);
|
||||
|
||||
let bm = yield PlacesUtils.bookmarks.insert({ type: PlacesUtils.bookmarks.TYPE_BOOKMARK,
|
||||
parentGuid: folder1.guid,
|
||||
url: new URL("http://example.com/") });
|
||||
let itemId = yield PlacesUtils.promiseItemId(bm.guid);
|
||||
|
||||
let folder2 = yield PlacesUtils.bookmarks.insert({ type: PlacesUtils.bookmarks.TYPE_FOLDER,
|
||||
parentGuid: PlacesUtils.bookmarks.unfiledGuid });
|
||||
let folder2Id = yield PlacesUtils.promiseItemId(folder2.guid);
|
||||
let folder2ParentId = yield PlacesUtils.promiseItemId(folder2.parentGuid);
|
||||
|
||||
bm.parentGuid = folder2.guid;
|
||||
bm = yield PlacesUtils.bookmarks.update(bm);
|
||||
let parentId = yield PlacesUtils.promiseItemId(bm.parentGuid);
|
||||
|
||||
let observer = expectNotifications();
|
||||
yield PlacesUtils.bookmarks.eraseEverything();
|
||||
|
||||
// Bookmarks should always be notified before their parents.
|
||||
observer.check([ { name: "onItemRemoved",
|
||||
arguments: [ itemId, parentId, bm.index, bm.type,
|
||||
bm.url, bm.guid, bm.parentGuid,
|
||||
Ci.nsINavBookmarksService.SOURCE_DEFAULT ] },
|
||||
{ name: "onItemRemoved",
|
||||
arguments: [ folder2Id, folder2ParentId, folder2.index,
|
||||
folder2.type, null, folder2.guid,
|
||||
folder2.parentGuid,
|
||||
Ci.nsINavBookmarksService.SOURCE_DEFAULT ] },
|
||||
{ name: "onItemRemoved",
|
||||
arguments: [ folder1Id, folder1ParentId, folder1.index,
|
||||
folder1.type, null, folder1.guid,
|
||||
folder1.parentGuid,
|
||||
Ci.nsINavBookmarksService.SOURCE_DEFAULT ] },
|
||||
]);
|
||||
});
|
||||
|
||||
add_task(function* reorder_notification() {
|
||||
let bookmarks = [
|
||||
{ type: PlacesUtils.bookmarks.TYPE_BOOKMARK,
|
||||
url: "http://example1.com/",
|
||||
parentGuid: PlacesUtils.bookmarks.unfiledGuid
|
||||
},
|
||||
{ type: PlacesUtils.bookmarks.TYPE_FOLDER,
|
||||
parentGuid: PlacesUtils.bookmarks.unfiledGuid
|
||||
},
|
||||
{ type: PlacesUtils.bookmarks.TYPE_SEPARATOR,
|
||||
parentGuid: PlacesUtils.bookmarks.unfiledGuid
|
||||
},
|
||||
{ type: PlacesUtils.bookmarks.TYPE_BOOKMARK,
|
||||
url: "http://example2.com/",
|
||||
parentGuid: PlacesUtils.bookmarks.unfiledGuid
|
||||
},
|
||||
{ type: PlacesUtils.bookmarks.TYPE_BOOKMARK,
|
||||
url: "http://example3.com/",
|
||||
parentGuid: PlacesUtils.bookmarks.unfiledGuid
|
||||
},
|
||||
];
|
||||
let sorted = [];
|
||||
for (let bm of bookmarks) {
|
||||
sorted.push(yield PlacesUtils.bookmarks.insert(bm));
|
||||
}
|
||||
|
||||
// Randomly reorder the array.
|
||||
sorted.sort(() => 0.5 - Math.random());
|
||||
|
||||
let observer = expectNotifications();
|
||||
yield PlacesUtils.bookmarks.reorder(PlacesUtils.bookmarks.unfiledGuid,
|
||||
sorted.map(bm => bm.guid));
|
||||
|
||||
let expectedNotifications = [];
|
||||
for (let i = 0; i < sorted.length; ++i) {
|
||||
let child = sorted[i];
|
||||
let childId = yield PlacesUtils.promiseItemId(child.guid);
|
||||
expectedNotifications.push({ name: "onItemMoved",
|
||||
arguments: [ childId,
|
||||
PlacesUtils.unfiledBookmarksFolderId,
|
||||
child.index,
|
||||
PlacesUtils.unfiledBookmarksFolderId,
|
||||
i,
|
||||
child.type,
|
||||
child.guid,
|
||||
child.parentGuid,
|
||||
child.parentGuid,
|
||||
Ci.nsINavBookmarksService.SOURCE_DEFAULT
|
||||
] });
|
||||
}
|
||||
observer.check(expectedNotifications);
|
||||
});
|
||||
|
||||
function expectNotifications() {
|
||||
let notifications = [];
|
||||
let observer = new Proxy(NavBookmarkObserver, {
|
||||
get(target, name) {
|
||||
if (name == "check") {
|
||||
PlacesUtils.bookmarks.removeObserver(observer);
|
||||
return expectedNotifications =>
|
||||
Assert.deepEqual(notifications, expectedNotifications);
|
||||
}
|
||||
|
||||
if (name.startsWith("onItem")) {
|
||||
return (...origArgs) => {
|
||||
let args = Array.from(origArgs, arg => {
|
||||
if (arg && arg instanceof Ci.nsIURI)
|
||||
return new URL(arg.spec);
|
||||
if (arg && typeof(arg) == "number" && arg >= Date.now() * 1000)
|
||||
return new Date(parseInt(arg/1000));
|
||||
return arg;
|
||||
});
|
||||
notifications.push({ name: name, arguments: args });
|
||||
}
|
||||
}
|
||||
|
||||
if (name in target)
|
||||
return target[name];
|
||||
return undefined;
|
||||
}
|
||||
});
|
||||
PlacesUtils.bookmarks.addObserver(observer, false);
|
||||
return observer;
|
||||
}
|
||||
|
||||
function run_test() {
|
||||
run_next_test();
|
||||
}
|
||||
|
|
@ -0,0 +1,204 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
add_task(function* invalid_input_throws() {
|
||||
Assert.throws(() => PlacesUtils.bookmarks.remove(),
|
||||
/Input should be a valid object/);
|
||||
Assert.throws(() => PlacesUtils.bookmarks.remove(null),
|
||||
/Input should be a valid object/);
|
||||
|
||||
Assert.throws(() => PlacesUtils.bookmarks.remove("test"),
|
||||
/Invalid value for property 'guid'/);
|
||||
Assert.throws(() => PlacesUtils.bookmarks.remove(123),
|
||||
/Invalid value for property 'guid'/);
|
||||
|
||||
Assert.throws(() => PlacesUtils.bookmarks.remove({ guid: "test" }),
|
||||
/Invalid value for property 'guid'/);
|
||||
Assert.throws(() => PlacesUtils.bookmarks.remove({ guid: null }),
|
||||
/Invalid value for property 'guid'/);
|
||||
Assert.throws(() => PlacesUtils.bookmarks.remove({ guid: 123 }),
|
||||
/Invalid value for property 'guid'/);
|
||||
|
||||
Assert.throws(() => PlacesUtils.bookmarks.remove({ parentGuid: "test" }),
|
||||
/Invalid value for property 'parentGuid'/);
|
||||
Assert.throws(() => PlacesUtils.bookmarks.remove({ parentGuid: null }),
|
||||
/Invalid value for property 'parentGuid'/);
|
||||
Assert.throws(() => PlacesUtils.bookmarks.remove({ parentGuid: 123 }),
|
||||
/Invalid value for property 'parentGuid'/);
|
||||
|
||||
Assert.throws(() => PlacesUtils.bookmarks.remove({ url: "http://te st/" }),
|
||||
/Invalid value for property 'url'/);
|
||||
Assert.throws(() => PlacesUtils.bookmarks.remove({ url: null }),
|
||||
/Invalid value for property 'url'/);
|
||||
Assert.throws(() => PlacesUtils.bookmarks.remove({ url: -10 }),
|
||||
/Invalid value for property 'url'/);
|
||||
});
|
||||
|
||||
add_task(function* remove_nonexistent_guid() {
|
||||
try {
|
||||
yield PlacesUtils.bookmarks.remove({ guid: "123456789012"});
|
||||
Assert.ok(false, "Should have thrown");
|
||||
} catch (ex) {
|
||||
Assert.ok(/No bookmarks found for the provided GUID/.test(ex));
|
||||
}
|
||||
});
|
||||
|
||||
add_task(function* remove_roots_fail() {
|
||||
let guids = [PlacesUtils.bookmarks.rootGuid,
|
||||
PlacesUtils.bookmarks.unfiledGuid,
|
||||
PlacesUtils.bookmarks.menuGuid,
|
||||
PlacesUtils.bookmarks.toolbarGuid,
|
||||
PlacesUtils.bookmarks.tagsGuid,
|
||||
PlacesUtils.bookmarks.mobileGuid];
|
||||
for (let guid of guids) {
|
||||
Assert.throws(() => PlacesUtils.bookmarks.remove(guid),
|
||||
/It's not possible to remove Places root folders/);
|
||||
}
|
||||
});
|
||||
|
||||
add_task(function* remove_normal_folder_under_root_succeeds() {
|
||||
let folder = yield PlacesUtils.bookmarks.insert({ parentGuid: PlacesUtils.bookmarks.rootGuid,
|
||||
type: PlacesUtils.bookmarks.TYPE_FOLDER });
|
||||
checkBookmarkObject(folder);
|
||||
let removed_folder = yield PlacesUtils.bookmarks.remove(folder);
|
||||
Assert.deepEqual(folder, removed_folder);
|
||||
Assert.strictEqual((yield PlacesUtils.bookmarks.fetch(folder.guid)), null);
|
||||
});
|
||||
|
||||
add_task(function* remove_bookmark() {
|
||||
let bm1 = yield PlacesUtils.bookmarks.insert({ parentGuid: PlacesUtils.bookmarks.unfiledGuid,
|
||||
type: PlacesUtils.bookmarks.TYPE_BOOKMARK,
|
||||
url: "http://example.com/",
|
||||
title: "a bookmark" });
|
||||
checkBookmarkObject(bm1);
|
||||
|
||||
let bm2 = yield PlacesUtils.bookmarks.remove(bm1.guid);
|
||||
checkBookmarkObject(bm2);
|
||||
|
||||
Assert.deepEqual(bm1, bm2);
|
||||
Assert.equal(bm2.parentGuid, PlacesUtils.bookmarks.unfiledGuid);
|
||||
Assert.equal(bm2.index, 0);
|
||||
Assert.deepEqual(bm2.dateAdded, bm2.lastModified);
|
||||
Assert.equal(bm2.type, PlacesUtils.bookmarks.TYPE_BOOKMARK);
|
||||
Assert.equal(bm2.url.href, "http://example.com/");
|
||||
Assert.equal(bm2.title, "a bookmark");
|
||||
});
|
||||
|
||||
|
||||
add_task(function* remove_bookmark_orphans() {
|
||||
let bm1 = yield PlacesUtils.bookmarks.insert({ parentGuid: PlacesUtils.bookmarks.unfiledGuid,
|
||||
type: PlacesUtils.bookmarks.TYPE_BOOKMARK,
|
||||
url: "http://example.com/",
|
||||
title: "a bookmark" });
|
||||
checkBookmarkObject(bm1);
|
||||
PlacesUtils.annotations.setItemAnnotation((yield PlacesUtils.promiseItemId(bm1.guid)),
|
||||
"testanno", "testvalue", 0, 0);
|
||||
|
||||
let bm2 = yield PlacesUtils.bookmarks.remove(bm1.guid);
|
||||
checkBookmarkObject(bm2);
|
||||
|
||||
// Check there are no orphan annotations.
|
||||
let conn = yield PlacesUtils.promiseDBConnection();
|
||||
let annoAttrs = yield conn.execute(`SELECT id, name FROM moz_anno_attributes`);
|
||||
// Bug 1306445 will eventually remove the mobile root anno.
|
||||
Assert.equal(annoAttrs.length, 1);
|
||||
Assert.equal(annoAttrs[0].getResultByName("name"), PlacesUtils.MOBILE_ROOT_ANNO);
|
||||
let annos = rows = yield conn.execute(`SELECT item_id, anno_attribute_id FROM moz_items_annos`);
|
||||
Assert.equal(annos.length, 1);
|
||||
Assert.equal(annos[0].getResultByName("item_id"), PlacesUtils.mobileFolderId);
|
||||
Assert.equal(annos[0].getResultByName("anno_attribute_id"), annoAttrs[0].getResultByName("id"));
|
||||
});
|
||||
|
||||
add_task(function* remove_bookmark_empty_title() {
|
||||
let bm1 = yield PlacesUtils.bookmarks.insert({ parentGuid: PlacesUtils.bookmarks.unfiledGuid,
|
||||
type: PlacesUtils.bookmarks.TYPE_BOOKMARK,
|
||||
url: "http://example.com/",
|
||||
title: "" });
|
||||
checkBookmarkObject(bm1);
|
||||
|
||||
let bm2 = yield PlacesUtils.bookmarks.remove(bm1.guid);
|
||||
checkBookmarkObject(bm2);
|
||||
|
||||
Assert.deepEqual(bm1, bm2);
|
||||
Assert.equal(bm2.index, 0);
|
||||
Assert.ok(!("title" in bm2));
|
||||
});
|
||||
|
||||
add_task(function* remove_folder() {
|
||||
let bm1 = yield PlacesUtils.bookmarks.insert({ parentGuid: PlacesUtils.bookmarks.unfiledGuid,
|
||||
type: PlacesUtils.bookmarks.TYPE_FOLDER,
|
||||
title: "a folder" });
|
||||
checkBookmarkObject(bm1);
|
||||
|
||||
let bm2 = yield PlacesUtils.bookmarks.remove(bm1.guid);
|
||||
checkBookmarkObject(bm2);
|
||||
|
||||
Assert.deepEqual(bm1, bm2);
|
||||
Assert.equal(bm2.parentGuid, PlacesUtils.bookmarks.unfiledGuid);
|
||||
Assert.equal(bm2.index, 0);
|
||||
Assert.deepEqual(bm2.dateAdded, bm2.lastModified);
|
||||
Assert.equal(bm2.type, PlacesUtils.bookmarks.TYPE_FOLDER);
|
||||
Assert.equal(bm2.title, "a folder");
|
||||
Assert.ok(!("url" in bm2));
|
||||
});
|
||||
|
||||
add_task(function* test_nested_contents_removed() {
|
||||
let folder1 = yield PlacesUtils.bookmarks.insert({ parentGuid: PlacesUtils.bookmarks.unfiledGuid,
|
||||
type: PlacesUtils.bookmarks.TYPE_FOLDER,
|
||||
title: "a folder" });
|
||||
let folder2 = yield PlacesUtils.bookmarks.insert({ parentGuid: folder1.guid,
|
||||
type: PlacesUtils.bookmarks.TYPE_FOLDER,
|
||||
title: "a folder" });
|
||||
let sep = yield PlacesUtils.bookmarks.insert({ parentGuid: folder2.guid,
|
||||
type: PlacesUtils.bookmarks.TYPE_SEPARATOR });
|
||||
yield PlacesUtils.bookmarks.remove(folder1);
|
||||
Assert.strictEqual((yield PlacesUtils.bookmarks.fetch(folder1.guid)), null);
|
||||
Assert.strictEqual((yield PlacesUtils.bookmarks.fetch(folder2.guid)), null);
|
||||
Assert.strictEqual((yield PlacesUtils.bookmarks.fetch(sep.guid)), null);
|
||||
});
|
||||
|
||||
add_task(function* remove_folder_empty_title() {
|
||||
let bm1 = yield PlacesUtils.bookmarks.insert({ parentGuid: PlacesUtils.bookmarks.unfiledGuid,
|
||||
type: PlacesUtils.bookmarks.TYPE_FOLDER,
|
||||
title: "" });
|
||||
checkBookmarkObject(bm1);
|
||||
|
||||
let bm2 = yield PlacesUtils.bookmarks.remove(bm1.guid);
|
||||
checkBookmarkObject(bm2);
|
||||
|
||||
Assert.deepEqual(bm1, bm2);
|
||||
Assert.equal(bm2.index, 0);
|
||||
Assert.ok(!("title" in bm2));
|
||||
});
|
||||
|
||||
add_task(function* remove_separator() {
|
||||
let bm1 = yield PlacesUtils.bookmarks.insert({ parentGuid: PlacesUtils.bookmarks.unfiledGuid,
|
||||
type: PlacesUtils.bookmarks.TYPE_SEPARATOR });
|
||||
checkBookmarkObject(bm1);
|
||||
|
||||
let bm2 = yield PlacesUtils.bookmarks.remove(bm1.guid);
|
||||
checkBookmarkObject(bm2);
|
||||
|
||||
Assert.deepEqual(bm1, bm2);
|
||||
Assert.equal(bm2.parentGuid, PlacesUtils.bookmarks.unfiledGuid);
|
||||
Assert.equal(bm2.index, 0);
|
||||
Assert.deepEqual(bm2.dateAdded, bm2.lastModified);
|
||||
Assert.equal(bm2.type, PlacesUtils.bookmarks.TYPE_SEPARATOR);
|
||||
Assert.ok(!("url" in bm2));
|
||||
Assert.ok(!("title" in bm2));
|
||||
});
|
||||
|
||||
add_task(function* test_nested_content_fails_when_not_allowed() {
|
||||
let folder1 = yield PlacesUtils.bookmarks.insert({ parentGuid: PlacesUtils.bookmarks.unfiledGuid,
|
||||
type: PlacesUtils.bookmarks.TYPE_FOLDER,
|
||||
title: "a folder" });
|
||||
yield PlacesUtils.bookmarks.insert({ parentGuid: folder1.guid,
|
||||
type: PlacesUtils.bookmarks.TYPE_FOLDER,
|
||||
title: "a folder" });
|
||||
yield Assert.rejects(PlacesUtils.bookmarks.remove(folder1, {preventRemovalOfNonEmptyFolders: true}),
|
||||
/Cannot remove a non-empty folder./);
|
||||
});
|
||||
|
||||
function run_test() {
|
||||
run_next_test();
|
||||
}
|
||||
|
|
@ -0,0 +1,177 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
add_task(function* invalid_input_throws() {
|
||||
Assert.throws(() => PlacesUtils.bookmarks.reorder(),
|
||||
/Invalid value for property 'guid'/);
|
||||
Assert.throws(() => PlacesUtils.bookmarks.reorder(null),
|
||||
/Invalid value for property 'guid'/);
|
||||
|
||||
Assert.throws(() => PlacesUtils.bookmarks.reorder("test"),
|
||||
/Invalid value for property 'guid'/);
|
||||
Assert.throws(() => PlacesUtils.bookmarks.reorder(123),
|
||||
/Invalid value for property 'guid'/);
|
||||
|
||||
Assert.throws(() => PlacesUtils.bookmarks.reorder({ guid: "test" }),
|
||||
/Invalid value for property 'guid'/);
|
||||
|
||||
Assert.throws(() => PlacesUtils.bookmarks.reorder("123456789012"),
|
||||
/Must provide a sorted array of children GUIDs./);
|
||||
Assert.throws(() => PlacesUtils.bookmarks.reorder("123456789012", {}),
|
||||
/Must provide a sorted array of children GUIDs./);
|
||||
Assert.throws(() => PlacesUtils.bookmarks.reorder("123456789012", null),
|
||||
/Must provide a sorted array of children GUIDs./);
|
||||
Assert.throws(() => PlacesUtils.bookmarks.reorder("123456789012", []),
|
||||
/Must provide a sorted array of children GUIDs./);
|
||||
|
||||
Assert.throws(() => PlacesUtils.bookmarks.reorder("123456789012", [ null ]),
|
||||
/Invalid GUID found in the sorted children array/);
|
||||
Assert.throws(() => PlacesUtils.bookmarks.reorder("123456789012", [ "" ]),
|
||||
/Invalid GUID found in the sorted children array/);
|
||||
Assert.throws(() => PlacesUtils.bookmarks.reorder("123456789012", [ {} ]),
|
||||
/Invalid GUID found in the sorted children array/);
|
||||
Assert.throws(() => PlacesUtils.bookmarks.reorder("123456789012", [ "012345678901", null ]),
|
||||
/Invalid GUID found in the sorted children array/);
|
||||
});
|
||||
|
||||
add_task(function* reorder_nonexistent_guid() {
|
||||
yield Assert.rejects(PlacesUtils.bookmarks.reorder("123456789012", [ "012345678901" ]),
|
||||
/No folder found for the provided GUID/,
|
||||
"Should throw for nonexisting guid");
|
||||
});
|
||||
|
||||
add_task(function* reorder() {
|
||||
let bookmarks = [
|
||||
{ url: "http://example1.com/",
|
||||
parentGuid: PlacesUtils.bookmarks.unfiledGuid
|
||||
},
|
||||
{ type: PlacesUtils.bookmarks.TYPE_FOLDER,
|
||||
parentGuid: PlacesUtils.bookmarks.unfiledGuid
|
||||
},
|
||||
{ type: PlacesUtils.bookmarks.TYPE_SEPARATOR,
|
||||
parentGuid: PlacesUtils.bookmarks.unfiledGuid
|
||||
},
|
||||
{ url: "http://example2.com/",
|
||||
parentGuid: PlacesUtils.bookmarks.unfiledGuid
|
||||
},
|
||||
{ url: "http://example3.com/",
|
||||
parentGuid: PlacesUtils.bookmarks.unfiledGuid
|
||||
}
|
||||
];
|
||||
|
||||
let sorted = [];
|
||||
for (let bm of bookmarks) {
|
||||
sorted.push(yield PlacesUtils.bookmarks.insert(bm));
|
||||
}
|
||||
|
||||
// Check the initial append sorting.
|
||||
Assert.ok(sorted.every((bm, i) => bm.index == i),
|
||||
"Initial bookmarks sorting is correct");
|
||||
|
||||
// Apply random sorting and run multiple tests.
|
||||
for (let t = 0; t < 4; t++) {
|
||||
sorted.sort(() => 0.5 - Math.random());
|
||||
let sortedGuids = sorted.map(child => child.guid);
|
||||
dump("Expected order: " + sortedGuids.join() + "\n");
|
||||
// Add a nonexisting guid to the array, to ensure nothing will break.
|
||||
sortedGuids.push("123456789012");
|
||||
yield PlacesUtils.bookmarks.reorder(PlacesUtils.bookmarks.unfiledGuid,
|
||||
sortedGuids);
|
||||
for (let i = 0; i < sorted.length; ++i) {
|
||||
let item = yield PlacesUtils.bookmarks.fetch(sorted[i].guid);
|
||||
Assert.equal(item.index, i);
|
||||
}
|
||||
}
|
||||
|
||||
do_print("Test partial sorting");
|
||||
// Try a partial sorting by passing only 2 entries.
|
||||
// The unspecified entries should retain the original order.
|
||||
sorted = [ sorted[1], sorted[0] ].concat(sorted.slice(2));
|
||||
let sortedGuids = [ sorted[0].guid, sorted[1].guid ];
|
||||
dump("Expected order: " + sorted.map(b => b.guid).join() + "\n");
|
||||
yield PlacesUtils.bookmarks.reorder(PlacesUtils.bookmarks.unfiledGuid,
|
||||
sortedGuids);
|
||||
for (let i = 0; i < sorted.length; ++i) {
|
||||
let item = yield PlacesUtils.bookmarks.fetch(sorted[i].guid);
|
||||
Assert.equal(item.index, i);
|
||||
}
|
||||
|
||||
// Use triangular numbers to detect skipped position.
|
||||
let db = yield PlacesUtils.promiseDBConnection();
|
||||
let rows = yield db.execute(
|
||||
`SELECT parent
|
||||
FROM moz_bookmarks
|
||||
GROUP BY parent
|
||||
HAVING (SUM(DISTINCT position + 1) - (count(*) * (count(*) + 1) / 2)) <> 0`);
|
||||
Assert.equal(rows.length, 0, "All the bookmarks should have consistent positions");
|
||||
});
|
||||
|
||||
add_task(function* move_and_reorder() {
|
||||
// Start clean.
|
||||
yield PlacesUtils.bookmarks.eraseEverything();
|
||||
|
||||
let bm1 = yield PlacesUtils.bookmarks.insert({
|
||||
url: "http://example1.com/",
|
||||
parentGuid: PlacesUtils.bookmarks.unfiledGuid
|
||||
});
|
||||
let f1 = yield PlacesUtils.bookmarks.insert({
|
||||
type: PlacesUtils.bookmarks.TYPE_FOLDER,
|
||||
parentGuid: PlacesUtils.bookmarks.unfiledGuid
|
||||
});
|
||||
let bm2 = yield PlacesUtils.bookmarks.insert({
|
||||
url: "http://example2.com/",
|
||||
parentGuid: f1.guid
|
||||
});
|
||||
let f2 = yield PlacesUtils.bookmarks.insert({
|
||||
type: PlacesUtils.bookmarks.TYPE_FOLDER,
|
||||
parentGuid: PlacesUtils.bookmarks.unfiledGuid
|
||||
});
|
||||
let bm3 = yield PlacesUtils.bookmarks.insert({
|
||||
url: "http://example3.com/",
|
||||
parentGuid: f2.guid
|
||||
});
|
||||
let bm4 = yield PlacesUtils.bookmarks.insert({
|
||||
url: "http://example4.com/",
|
||||
parentGuid: f2.guid
|
||||
});
|
||||
let bm5 = yield PlacesUtils.bookmarks.insert({
|
||||
url: "http://example5.com/",
|
||||
parentGuid: f2.guid
|
||||
});
|
||||
|
||||
// Invert f2 children.
|
||||
// This is critical to reproduce the bug, cause it inverts the position
|
||||
// compared to the natural insertion order.
|
||||
yield PlacesUtils.bookmarks.reorder(f2.guid, [bm5.guid, bm4.guid, bm3.guid]);
|
||||
|
||||
bm1.parentGuid = f1.guid;
|
||||
bm1.index = 0;
|
||||
yield PlacesUtils.bookmarks.update(bm1);
|
||||
|
||||
bm1 = yield PlacesUtils.bookmarks.fetch(bm1.guid);
|
||||
Assert.equal(bm1.index, 0);
|
||||
bm2 = yield PlacesUtils.bookmarks.fetch(bm2.guid);
|
||||
Assert.equal(bm2.index, 1);
|
||||
bm3 = yield PlacesUtils.bookmarks.fetch(bm3.guid);
|
||||
Assert.equal(bm3.index, 2);
|
||||
bm4 = yield PlacesUtils.bookmarks.fetch(bm4.guid);
|
||||
Assert.equal(bm4.index, 1);
|
||||
bm5 = yield PlacesUtils.bookmarks.fetch(bm5.guid);
|
||||
Assert.equal(bm5.index, 0);
|
||||
|
||||
// No-op reorder on f1 children.
|
||||
// Nothing should change. Though, due to bug 1293365 this was causing children
|
||||
// of other folders to get messed up.
|
||||
yield PlacesUtils.bookmarks.reorder(f1.guid, [bm1.guid, bm2.guid]);
|
||||
|
||||
bm1 = yield PlacesUtils.bookmarks.fetch(bm1.guid);
|
||||
Assert.equal(bm1.index, 0);
|
||||
bm2 = yield PlacesUtils.bookmarks.fetch(bm2.guid);
|
||||
Assert.equal(bm2.index, 1);
|
||||
bm3 = yield PlacesUtils.bookmarks.fetch(bm3.guid);
|
||||
Assert.equal(bm3.index, 2);
|
||||
bm4 = yield PlacesUtils.bookmarks.fetch(bm4.guid);
|
||||
Assert.equal(bm4.index, 1);
|
||||
bm5 = yield PlacesUtils.bookmarks.fetch(bm5.guid);
|
||||
Assert.equal(bm5.index, 0);
|
||||
});
|
||||
|
|
@ -0,0 +1,223 @@
|
|||
add_task(function* invalid_input_throws() {
|
||||
Assert.throws(() => PlacesUtils.bookmarks.search(),
|
||||
/Query object is required/);
|
||||
Assert.throws(() => PlacesUtils.bookmarks.search(null),
|
||||
/Query object is required/);
|
||||
Assert.throws(() => PlacesUtils.bookmarks.search({title: 50}),
|
||||
/Title option must be a string/);
|
||||
Assert.throws(() => PlacesUtils.bookmarks.search({url: {url: "wombat"}}),
|
||||
/Url option must be a string or a URL object/);
|
||||
Assert.throws(() => PlacesUtils.bookmarks.search(50),
|
||||
/Query must be an object or a string/);
|
||||
Assert.throws(() => PlacesUtils.bookmarks.search(true),
|
||||
/Query must be an object or a string/);
|
||||
});
|
||||
|
||||
add_task(function* search_bookmark() {
|
||||
yield PlacesUtils.bookmarks.eraseEverything();
|
||||
|
||||
let bm1 = yield PlacesUtils.bookmarks.insert({ parentGuid: PlacesUtils.bookmarks.unfiledGuid,
|
||||
url: "http://example.com/",
|
||||
title: "a bookmark" });
|
||||
let bm2 = yield PlacesUtils.bookmarks.insert({ parentGuid: PlacesUtils.bookmarks.unfiledGuid,
|
||||
url: "http://example.org/",
|
||||
title: "another bookmark" });
|
||||
let bm3 = yield PlacesUtils.bookmarks.insert({ parentGuid: PlacesUtils.bookmarks.menuGuid,
|
||||
url: "http://menu.org/",
|
||||
title: "an on-menu bookmark" });
|
||||
let bm4 = yield PlacesUtils.bookmarks.insert({ parentGuid: PlacesUtils.bookmarks.toolbarGuid,
|
||||
url: "http://toolbar.org/",
|
||||
title: "an on-toolbar bookmark" });
|
||||
checkBookmarkObject(bm1);
|
||||
checkBookmarkObject(bm2);
|
||||
checkBookmarkObject(bm3);
|
||||
checkBookmarkObject(bm4);
|
||||
|
||||
// finds a result by query
|
||||
let results = yield PlacesUtils.bookmarks.search("example.com");
|
||||
Assert.equal(results.length, 1);
|
||||
checkBookmarkObject(results[0]);
|
||||
Assert.deepEqual(bm1, results[0]);
|
||||
|
||||
// finds multiple results
|
||||
results = yield PlacesUtils.bookmarks.search("example");
|
||||
Assert.equal(results.length, 2);
|
||||
checkBookmarkObject(results[0]);
|
||||
checkBookmarkObject(results[1]);
|
||||
|
||||
// finds menu bookmarks
|
||||
results = yield PlacesUtils.bookmarks.search("an on-menu bookmark");
|
||||
Assert.equal(results.length, 1);
|
||||
checkBookmarkObject(results[0]);
|
||||
Assert.deepEqual(bm3, results[0]);
|
||||
|
||||
// finds toolbar bookmarks
|
||||
results = yield PlacesUtils.bookmarks.search("an on-toolbar bookmark");
|
||||
Assert.equal(results.length, 1);
|
||||
checkBookmarkObject(results[0]);
|
||||
Assert.deepEqual(bm4, results[0]);
|
||||
|
||||
yield PlacesUtils.bookmarks.eraseEverything();
|
||||
});
|
||||
|
||||
add_task(function* search_bookmark_by_query_object() {
|
||||
let bm1 = yield PlacesUtils.bookmarks.insert({ parentGuid: PlacesUtils.bookmarks.unfiledGuid,
|
||||
url: "http://example.com/",
|
||||
title: "a bookmark" });
|
||||
let bm2 = yield PlacesUtils.bookmarks.insert({ parentGuid: PlacesUtils.bookmarks.unfiledGuid,
|
||||
url: "http://example.org/",
|
||||
title: "another bookmark" });
|
||||
checkBookmarkObject(bm1);
|
||||
checkBookmarkObject(bm2);
|
||||
|
||||
let results = yield PlacesUtils.bookmarks.search({query: "example.com"});
|
||||
Assert.equal(results.length, 1);
|
||||
checkBookmarkObject(results[0]);
|
||||
|
||||
Assert.deepEqual(bm1, results[0]);
|
||||
|
||||
results = yield PlacesUtils.bookmarks.search({query: "example"});
|
||||
Assert.equal(results.length, 2);
|
||||
checkBookmarkObject(results[0]);
|
||||
checkBookmarkObject(results[1]);
|
||||
|
||||
yield PlacesUtils.bookmarks.eraseEverything();
|
||||
});
|
||||
|
||||
add_task(function* search_bookmark_by_url() {
|
||||
let bm1 = yield PlacesUtils.bookmarks.insert({ parentGuid: PlacesUtils.bookmarks.unfiledGuid,
|
||||
url: "http://example.com/",
|
||||
title: "a bookmark" });
|
||||
let bm2 = yield PlacesUtils.bookmarks.insert({ parentGuid: PlacesUtils.bookmarks.unfiledGuid,
|
||||
url: "http://example.org/path",
|
||||
title: "another bookmark" });
|
||||
let bm3 = yield PlacesUtils.bookmarks.insert({ parentGuid: PlacesUtils.bookmarks.unfiledGuid,
|
||||
url: "http://example.org/path",
|
||||
title: "third bookmark" });
|
||||
checkBookmarkObject(bm1);
|
||||
checkBookmarkObject(bm2);
|
||||
checkBookmarkObject(bm3);
|
||||
|
||||
// finds the correct result by url
|
||||
let results = yield PlacesUtils.bookmarks.search({url: "http://example.com/"});
|
||||
Assert.equal(results.length, 1);
|
||||
checkBookmarkObject(results[0]);
|
||||
Assert.deepEqual(bm1, results[0]);
|
||||
|
||||
// normalizes the url
|
||||
results = yield PlacesUtils.bookmarks.search({url: "http:/example.com"});
|
||||
Assert.equal(results.length, 1);
|
||||
checkBookmarkObject(results[0]);
|
||||
Assert.deepEqual(bm1, results[0]);
|
||||
|
||||
// returns multiple matches
|
||||
results = yield PlacesUtils.bookmarks.search({url: "http://example.org/path"});
|
||||
Assert.equal(results.length, 2);
|
||||
|
||||
// requires exact match
|
||||
results = yield PlacesUtils.bookmarks.search({url: "http://example.org/"});
|
||||
Assert.equal(results.length, 0);
|
||||
|
||||
yield PlacesUtils.bookmarks.eraseEverything();
|
||||
});
|
||||
|
||||
add_task(function* search_bookmark_by_title() {
|
||||
let bm1 = yield PlacesUtils.bookmarks.insert({ parentGuid: PlacesUtils.bookmarks.unfiledGuid,
|
||||
url: "http://example.com/",
|
||||
title: "a bookmark" });
|
||||
let bm2 = yield PlacesUtils.bookmarks.insert({ parentGuid: PlacesUtils.bookmarks.unfiledGuid,
|
||||
url: "http://example.org/path",
|
||||
title: "another bookmark" });
|
||||
let bm3 = yield PlacesUtils.bookmarks.insert({ parentGuid: PlacesUtils.bookmarks.unfiledGuid,
|
||||
url: "http://example.net/",
|
||||
title: "another bookmark" });
|
||||
checkBookmarkObject(bm1);
|
||||
checkBookmarkObject(bm2);
|
||||
checkBookmarkObject(bm3);
|
||||
|
||||
// finds the correct result by title
|
||||
let results = yield PlacesUtils.bookmarks.search({title: "a bookmark"});
|
||||
Assert.equal(results.length, 1);
|
||||
checkBookmarkObject(results[0]);
|
||||
Assert.deepEqual(bm1, results[0]);
|
||||
|
||||
// returns multiple matches
|
||||
results = yield PlacesUtils.bookmarks.search({title: "another bookmark"});
|
||||
Assert.equal(results.length, 2);
|
||||
|
||||
// requires exact match
|
||||
results = yield PlacesUtils.bookmarks.search({title: "bookmark"});
|
||||
Assert.equal(results.length, 0);
|
||||
|
||||
yield PlacesUtils.bookmarks.eraseEverything();
|
||||
});
|
||||
|
||||
add_task(function* search_bookmark_combinations() {
|
||||
let bm1 = yield PlacesUtils.bookmarks.insert({ parentGuid: PlacesUtils.bookmarks.unfiledGuid,
|
||||
url: "http://example.com/",
|
||||
title: "a bookmark" });
|
||||
let bm2 = yield PlacesUtils.bookmarks.insert({ parentGuid: PlacesUtils.bookmarks.unfiledGuid,
|
||||
url: "http://example.org/path",
|
||||
title: "another bookmark" });
|
||||
let bm3 = yield PlacesUtils.bookmarks.insert({ parentGuid: PlacesUtils.bookmarks.unfiledGuid,
|
||||
url: "http://example.net/",
|
||||
title: "third bookmark" });
|
||||
checkBookmarkObject(bm1);
|
||||
checkBookmarkObject(bm2);
|
||||
checkBookmarkObject(bm3);
|
||||
|
||||
// finds the correct result if title and url match
|
||||
let results = yield PlacesUtils.bookmarks.search({url: "http://example.com/", title: "a bookmark"});
|
||||
Assert.equal(results.length, 1);
|
||||
checkBookmarkObject(results[0]);
|
||||
Assert.deepEqual(bm1, results[0]);
|
||||
|
||||
// does not match if query is not matching but url and title match
|
||||
results = yield PlacesUtils.bookmarks.search({url: "http://example.com/", title: "a bookmark", query: "nonexistent"});
|
||||
Assert.equal(results.length, 0);
|
||||
|
||||
// does not match if one parameter is not matching
|
||||
results = yield PlacesUtils.bookmarks.search({url: "http://what.ever", title: "a bookmark"});
|
||||
Assert.equal(results.length, 0);
|
||||
|
||||
// query only matches if other fields match as well
|
||||
results = yield PlacesUtils.bookmarks.search({query: "bookmark", url: "http://example.net/"});
|
||||
Assert.equal(results.length, 1);
|
||||
checkBookmarkObject(results[0]);
|
||||
Assert.deepEqual(bm3, results[0]);
|
||||
|
||||
// non-matching query will also return no results
|
||||
results = yield PlacesUtils.bookmarks.search({query: "nonexistent", url: "http://example.net/"});
|
||||
Assert.equal(results.length, 0);
|
||||
|
||||
yield PlacesUtils.bookmarks.eraseEverything();
|
||||
});
|
||||
|
||||
add_task(function* search_folder() {
|
||||
let folder = yield PlacesUtils.bookmarks.insert({ parentGuid: PlacesUtils.bookmarks.menuGuid,
|
||||
type: PlacesUtils.bookmarks.TYPE_FOLDER,
|
||||
title: "a test folder" });
|
||||
let bm = yield PlacesUtils.bookmarks.insert({ parentGuid: folder.guid,
|
||||
url: "http://example.com/",
|
||||
title: "a bookmark" });
|
||||
checkBookmarkObject(folder);
|
||||
checkBookmarkObject(bm);
|
||||
|
||||
// also finds folders
|
||||
let results = yield PlacesUtils.bookmarks.search("a test folder");
|
||||
Assert.equal(results.length, 1);
|
||||
checkBookmarkObject(results[0]);
|
||||
Assert.equal(folder.title, results[0].title);
|
||||
Assert.equal(folder.type, results[0].type);
|
||||
Assert.equal(folder.parentGuid, results[0].parentGuid);
|
||||
|
||||
// finds elements in folders
|
||||
results = yield PlacesUtils.bookmarks.search("example.com");
|
||||
Assert.equal(results.length, 1);
|
||||
checkBookmarkObject(results[0]);
|
||||
Assert.deepEqual(bm, results[0]);
|
||||
Assert.equal(folder.guid, results[0].parentGuid);
|
||||
|
||||
yield PlacesUtils.bookmarks.eraseEverything();
|
||||
});
|
||||
|
||||
|
|
@ -0,0 +1,414 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
add_task(function* invalid_input_throws() {
|
||||
Assert.throws(() => PlacesUtils.bookmarks.update(),
|
||||
/Input should be a valid object/);
|
||||
Assert.throws(() => PlacesUtils.bookmarks.update(null),
|
||||
/Input should be a valid object/);
|
||||
Assert.throws(() => PlacesUtils.bookmarks.update({}),
|
||||
/The following properties were expected/);
|
||||
|
||||
Assert.throws(() => PlacesUtils.bookmarks.update({ guid: "test" }),
|
||||
/Invalid value for property 'guid'/);
|
||||
Assert.throws(() => PlacesUtils.bookmarks.update({ guid: null }),
|
||||
/Invalid value for property 'guid'/);
|
||||
Assert.throws(() => PlacesUtils.bookmarks.update({ guid: 123 }),
|
||||
/Invalid value for property 'guid'/);
|
||||
|
||||
Assert.throws(() => PlacesUtils.bookmarks.update({ parentGuid: "test" }),
|
||||
/Invalid value for property 'parentGuid'/);
|
||||
Assert.throws(() => PlacesUtils.bookmarks.update({ parentGuid: null }),
|
||||
/Invalid value for property 'parentGuid'/);
|
||||
Assert.throws(() => PlacesUtils.bookmarks.update({ parentGuid: 123 }),
|
||||
/Invalid value for property 'parentGuid'/);
|
||||
|
||||
Assert.throws(() => PlacesUtils.bookmarks.update({ index: "1" }),
|
||||
/Invalid value for property 'index'/);
|
||||
Assert.throws(() => PlacesUtils.bookmarks.update({ index: -10 }),
|
||||
/Invalid value for property 'index'/);
|
||||
|
||||
Assert.throws(() => PlacesUtils.bookmarks.update({ dateAdded: -10 }),
|
||||
/Invalid value for property 'dateAdded'/);
|
||||
Assert.throws(() => PlacesUtils.bookmarks.update({ dateAdded: "today" }),
|
||||
/Invalid value for property 'dateAdded'/);
|
||||
Assert.throws(() => PlacesUtils.bookmarks.update({ dateAdded: Date.now() }),
|
||||
/Invalid value for property 'dateAdded'/);
|
||||
|
||||
Assert.throws(() => PlacesUtils.bookmarks.update({ lastModified: -10 }),
|
||||
/Invalid value for property 'lastModified'/);
|
||||
Assert.throws(() => PlacesUtils.bookmarks.update({ lastModified: "today" }),
|
||||
/Invalid value for property 'lastModified'/);
|
||||
Assert.throws(() => PlacesUtils.bookmarks.update({ lastModified: Date.now() }),
|
||||
/Invalid value for property 'lastModified'/);
|
||||
|
||||
Assert.throws(() => PlacesUtils.bookmarks.update({ type: -1 }),
|
||||
/Invalid value for property 'type'/);
|
||||
Assert.throws(() => PlacesUtils.bookmarks.update({ type: 100 }),
|
||||
/Invalid value for property 'type'/);
|
||||
Assert.throws(() => PlacesUtils.bookmarks.update({ type: "bookmark" }),
|
||||
/Invalid value for property 'type'/);
|
||||
|
||||
Assert.throws(() => PlacesUtils.bookmarks.update({ url: 10 }),
|
||||
/Invalid value for property 'url'/);
|
||||
Assert.throws(() => PlacesUtils.bookmarks.update({ url: "http://te st" }),
|
||||
/Invalid value for property 'url'/);
|
||||
let longurl = "http://www.example.com/";
|
||||
for (let i = 0; i < 65536; i++) {
|
||||
longurl += "a";
|
||||
}
|
||||
Assert.throws(() => PlacesUtils.bookmarks.update({ url: longurl }),
|
||||
/Invalid value for property 'url'/);
|
||||
|
||||
Assert.throws(() => PlacesUtils.bookmarks.update({ url: NetUtil.newURI(longurl) }),
|
||||
/Invalid value for property 'url'/);
|
||||
Assert.throws(() => PlacesUtils.bookmarks.update({ url: "te st" }),
|
||||
/Invalid value for property 'url'/);
|
||||
|
||||
Assert.throws(() => PlacesUtils.bookmarks.update({ title: -1 }),
|
||||
/Invalid value for property 'title'/);
|
||||
Assert.throws(() => PlacesUtils.bookmarks.update({ title: {} }),
|
||||
/Invalid value for property 'title'/);
|
||||
|
||||
Assert.throws(() => PlacesUtils.bookmarks.update({ guid: "123456789012" }),
|
||||
/Not enough properties to update/);
|
||||
|
||||
Assert.throws(() => PlacesUtils.bookmarks.update({ guid: "123456789012",
|
||||
parentGuid: "012345678901" }),
|
||||
/The following properties were expected: index/);
|
||||
});
|
||||
|
||||
add_task(function* nonexisting_bookmark_throws() {
|
||||
try {
|
||||
yield PlacesUtils.bookmarks.update({ guid: "123456789012",
|
||||
title: "test" });
|
||||
Assert.ok(false, "Should have thrown");
|
||||
} catch (ex) {
|
||||
Assert.ok(/No bookmarks found for the provided GUID/.test(ex));
|
||||
}
|
||||
});
|
||||
|
||||
add_task(function* invalid_properties_for_existing_bookmark() {
|
||||
let bm = yield PlacesUtils.bookmarks.insert({ type: PlacesUtils.bookmarks.TYPE_BOOKMARK,
|
||||
parentGuid: PlacesUtils.bookmarks.unfiledGuid,
|
||||
url: "http://example.com/" });
|
||||
|
||||
try {
|
||||
yield PlacesUtils.bookmarks.update({ guid: bm.guid,
|
||||
type: PlacesUtils.bookmarks.TYPE_FOLDER });
|
||||
Assert.ok(false, "Should have thrown");
|
||||
} catch (ex) {
|
||||
Assert.ok(/The bookmark type cannot be changed/.test(ex));
|
||||
}
|
||||
|
||||
try {
|
||||
yield PlacesUtils.bookmarks.update({ guid: bm.guid,
|
||||
dateAdded: new Date() });
|
||||
Assert.ok(false, "Should have thrown");
|
||||
} catch (ex) {
|
||||
Assert.ok(/The bookmark dateAdded cannot be changed/.test(ex));
|
||||
}
|
||||
|
||||
try {
|
||||
yield PlacesUtils.bookmarks.update({ guid: bm.guid,
|
||||
dateAdded: new Date() });
|
||||
Assert.ok(false, "Should have thrown");
|
||||
} catch (ex) {
|
||||
Assert.ok(/The bookmark dateAdded cannot be changed/.test(ex));
|
||||
}
|
||||
|
||||
try {
|
||||
yield PlacesUtils.bookmarks.update({ guid: bm.guid,
|
||||
parentGuid: "123456789012",
|
||||
index: 1 });
|
||||
Assert.ok(false, "Should have thrown");
|
||||
} catch (ex) {
|
||||
Assert.ok(/No bookmarks found for the provided parentGuid/.test(ex));
|
||||
}
|
||||
|
||||
let past = new Date(Date.now() - 86400000);
|
||||
try {
|
||||
yield PlacesUtils.bookmarks.update({ guid: bm.guid,
|
||||
lastModified: past });
|
||||
Assert.ok(false, "Should have thrown");
|
||||
} catch (ex) {
|
||||
Assert.ok(/Invalid value for property 'lastModified'/.test(ex));
|
||||
}
|
||||
|
||||
let folder = yield PlacesUtils.bookmarks.insert({ type: PlacesUtils.bookmarks.TYPE_FOLDER,
|
||||
parentGuid: PlacesUtils.bookmarks.unfiledGuid });
|
||||
try {
|
||||
yield PlacesUtils.bookmarks.update({ guid: folder.guid,
|
||||
url: "http://example.com/" });
|
||||
Assert.ok(false, "Should have thrown");
|
||||
} catch (ex) {
|
||||
Assert.ok(/Invalid value for property 'url'/.test(ex));
|
||||
}
|
||||
|
||||
let separator = yield PlacesUtils.bookmarks.insert({ type: PlacesUtils.bookmarks.TYPE_SEPARATOR,
|
||||
parentGuid: PlacesUtils.bookmarks.unfiledGuid });
|
||||
try {
|
||||
yield PlacesUtils.bookmarks.update({ guid: separator.guid,
|
||||
url: "http://example.com/" });
|
||||
Assert.ok(false, "Should have thrown");
|
||||
} catch (ex) {
|
||||
Assert.ok(/Invalid value for property 'url'/.test(ex));
|
||||
}
|
||||
try {
|
||||
yield PlacesUtils.bookmarks.update({ guid: separator.guid,
|
||||
title: "test" });
|
||||
Assert.ok(false, "Should have thrown");
|
||||
} catch (ex) {
|
||||
Assert.ok(/Invalid value for property 'title'/.test(ex));
|
||||
}
|
||||
});
|
||||
|
||||
add_task(function* long_title_trim() {
|
||||
let longtitle = "a";
|
||||
for (let i = 0; i < 4096; i++) {
|
||||
longtitle += "a";
|
||||
}
|
||||
let bm = yield PlacesUtils.bookmarks.insert({ parentGuid: PlacesUtils.bookmarks.unfiledGuid,
|
||||
type: PlacesUtils.bookmarks.TYPE_FOLDER,
|
||||
title: "title" });
|
||||
checkBookmarkObject(bm);
|
||||
|
||||
bm = yield PlacesUtils.bookmarks.update({ guid: bm.guid,
|
||||
title: longtitle });
|
||||
let newTitle = bm.title;
|
||||
Assert.equal(newTitle.length, 4096, "title should have been trimmed");
|
||||
|
||||
bm = yield PlacesUtils.bookmarks.fetch(bm.guid);
|
||||
Assert.equal(bm.title, newTitle);
|
||||
});
|
||||
|
||||
add_task(function* update_lastModified() {
|
||||
let yesterday = new Date(Date.now() - 86400000);
|
||||
let bm = yield PlacesUtils.bookmarks.insert({ parentGuid: PlacesUtils.bookmarks.unfiledGuid,
|
||||
type: PlacesUtils.bookmarks.TYPE_FOLDER,
|
||||
title: "title",
|
||||
dateAdded: yesterday });
|
||||
checkBookmarkObject(bm);
|
||||
Assert.deepEqual(bm.lastModified, yesterday);
|
||||
|
||||
let time = new Date();
|
||||
bm = yield PlacesUtils.bookmarks.update({ guid: bm.guid,
|
||||
lastModified: time });
|
||||
checkBookmarkObject(bm);
|
||||
Assert.deepEqual(bm.lastModified, time);
|
||||
|
||||
bm = yield PlacesUtils.bookmarks.fetch(bm.guid);
|
||||
Assert.deepEqual(bm.lastModified, time);
|
||||
|
||||
bm = yield PlacesUtils.bookmarks.update({ guid: bm.guid,
|
||||
lastModified: yesterday });
|
||||
Assert.deepEqual(bm.lastModified, yesterday);
|
||||
|
||||
bm = yield PlacesUtils.bookmarks.update({ guid: bm.guid,
|
||||
title: "title2" });
|
||||
Assert.ok(bm.lastModified >= time);
|
||||
|
||||
bm = yield PlacesUtils.bookmarks.update({ guid: bm.guid,
|
||||
title: "" });
|
||||
Assert.ok(!("title" in bm));
|
||||
|
||||
bm = yield PlacesUtils.bookmarks.fetch(bm.guid);
|
||||
Assert.ok(!("title" in bm));
|
||||
});
|
||||
|
||||
add_task(function* update_url() {
|
||||
let bm = yield PlacesUtils.bookmarks.insert({ parentGuid: PlacesUtils.bookmarks.unfiledGuid,
|
||||
type: PlacesUtils.bookmarks.TYPE_BOOKMARK,
|
||||
url: "http://example.com/",
|
||||
title: "title" });
|
||||
checkBookmarkObject(bm);
|
||||
let lastModified = bm.lastModified;
|
||||
let frecency = frecencyForUrl(bm.url);
|
||||
Assert.ok(frecency > 0, "Check frecency has been updated");
|
||||
|
||||
bm = yield PlacesUtils.bookmarks.update({ guid: bm.guid,
|
||||
url: "http://mozilla.org/" });
|
||||
checkBookmarkObject(bm);
|
||||
Assert.ok(bm.lastModified >= lastModified);
|
||||
Assert.equal(bm.url.href, "http://mozilla.org/");
|
||||
|
||||
bm = yield PlacesUtils.bookmarks.fetch(bm.guid);
|
||||
Assert.equal(bm.url.href, "http://mozilla.org/");
|
||||
Assert.ok(bm.lastModified >= lastModified);
|
||||
|
||||
Assert.equal(frecencyForUrl("http://example.com/"), frecency, "Check frecency for example.com");
|
||||
Assert.equal(frecencyForUrl("http://mozilla.org/"), frecency, "Check frecency for mozilla.org");
|
||||
});
|
||||
|
||||
add_task(function* update_index() {
|
||||
let parent = yield PlacesUtils.bookmarks.insert({ parentGuid: PlacesUtils.bookmarks.unfiledGuid,
|
||||
type: PlacesUtils.bookmarks.TYPE_FOLDER }) ;
|
||||
let f1 = yield PlacesUtils.bookmarks.insert({ parentGuid: parent.guid,
|
||||
type: PlacesUtils.bookmarks.TYPE_FOLDER });
|
||||
Assert.equal(f1.index, 0);
|
||||
let f2 = yield PlacesUtils.bookmarks.insert({ parentGuid: parent.guid,
|
||||
type: PlacesUtils.bookmarks.TYPE_FOLDER });
|
||||
Assert.equal(f2.index, 1);
|
||||
let f3 = yield PlacesUtils.bookmarks.insert({ parentGuid: parent.guid,
|
||||
type: PlacesUtils.bookmarks.TYPE_FOLDER });
|
||||
Assert.equal(f3.index, 2);
|
||||
let lastModified = f1.lastModified;
|
||||
|
||||
f1 = yield PlacesUtils.bookmarks.update({ guid: f1.guid,
|
||||
parentGuid: f1.parentGuid,
|
||||
index: 1});
|
||||
checkBookmarkObject(f1);
|
||||
Assert.equal(f1.index, 1);
|
||||
Assert.ok(f1.lastModified >= lastModified);
|
||||
|
||||
parent = yield PlacesUtils.bookmarks.fetch(f1.parentGuid);
|
||||
Assert.deepEqual(parent.lastModified, f1.lastModified);
|
||||
|
||||
f2 = yield PlacesUtils.bookmarks.fetch(f2.guid);
|
||||
Assert.equal(f2.index, 0);
|
||||
|
||||
f3 = yield PlacesUtils.bookmarks.fetch(f3.guid);
|
||||
Assert.equal(f3.index, 2);
|
||||
|
||||
f3 = yield PlacesUtils.bookmarks.update({ guid: f3.guid,
|
||||
index: 0 });
|
||||
f1 = yield PlacesUtils.bookmarks.fetch(f1.guid);
|
||||
Assert.equal(f1.index, 2);
|
||||
|
||||
f2 = yield PlacesUtils.bookmarks.fetch(f2.guid);
|
||||
Assert.equal(f2.index, 1);
|
||||
});
|
||||
|
||||
add_task(function* update_move_folder_into_descendant_throws() {
|
||||
let parent = yield PlacesUtils.bookmarks.insert({ parentGuid: PlacesUtils.bookmarks.unfiledGuid,
|
||||
type: PlacesUtils.bookmarks.TYPE_FOLDER }) ;
|
||||
let descendant = yield PlacesUtils.bookmarks.insert({ parentGuid: parent.guid,
|
||||
type: PlacesUtils.bookmarks.TYPE_FOLDER });
|
||||
|
||||
try {
|
||||
yield PlacesUtils.bookmarks.update({ guid: parent.guid,
|
||||
parentGuid: parent.guid,
|
||||
index: 0 });
|
||||
Assert.ok(false, "Should have thrown");
|
||||
} catch (ex) {
|
||||
Assert.ok(/Cannot insert a folder into itself or one of its descendants/.test(ex));
|
||||
}
|
||||
|
||||
try {
|
||||
yield PlacesUtils.bookmarks.update({ guid: parent.guid,
|
||||
parentGuid: descendant.guid,
|
||||
index: 0 });
|
||||
Assert.ok(false, "Should have thrown");
|
||||
} catch (ex) {
|
||||
Assert.ok(/Cannot insert a folder into itself or one of its descendants/.test(ex));
|
||||
}
|
||||
});
|
||||
|
||||
add_task(function* update_move() {
|
||||
let parent = yield PlacesUtils.bookmarks.insert({ parentGuid: PlacesUtils.bookmarks.unfiledGuid,
|
||||
type: PlacesUtils.bookmarks.TYPE_FOLDER }) ;
|
||||
let bm = yield PlacesUtils.bookmarks.insert({ parentGuid: parent.guid,
|
||||
url: "http://example.com/",
|
||||
type: PlacesUtils.bookmarks.TYPE_BOOKMARK }) ;
|
||||
let descendant = yield PlacesUtils.bookmarks.insert({ parentGuid: parent.guid,
|
||||
type: PlacesUtils.bookmarks.TYPE_FOLDER });
|
||||
Assert.equal(descendant.index, 1);
|
||||
let lastModified = bm.lastModified;
|
||||
|
||||
// This is moving to a nonexisting index by purpose, it will be appended.
|
||||
bm = yield PlacesUtils.bookmarks.update({ guid: bm.guid,
|
||||
parentGuid: descendant.guid,
|
||||
index: 1 });
|
||||
checkBookmarkObject(bm);
|
||||
Assert.equal(bm.parentGuid, descendant.guid);
|
||||
Assert.equal(bm.index, 0);
|
||||
Assert.ok(bm.lastModified >= lastModified);
|
||||
|
||||
parent = yield PlacesUtils.bookmarks.fetch(parent.guid);
|
||||
descendant = yield PlacesUtils.bookmarks.fetch(descendant.guid);
|
||||
Assert.deepEqual(parent.lastModified, bm.lastModified);
|
||||
Assert.deepEqual(descendant.lastModified, bm.lastModified);
|
||||
Assert.equal(descendant.index, 0);
|
||||
|
||||
bm = yield PlacesUtils.bookmarks.fetch(bm.guid);
|
||||
Assert.equal(bm.parentGuid, descendant.guid);
|
||||
Assert.equal(bm.index, 0);
|
||||
|
||||
bm = yield PlacesUtils.bookmarks.update({ guid: bm.guid,
|
||||
parentGuid: parent.guid,
|
||||
index: 0 });
|
||||
Assert.equal(bm.parentGuid, parent.guid);
|
||||
Assert.equal(bm.index, 0);
|
||||
|
||||
descendant = yield PlacesUtils.bookmarks.fetch(descendant.guid);
|
||||
Assert.equal(descendant.index, 1);
|
||||
});
|
||||
|
||||
add_task(function* update_move_append() {
|
||||
let folder_a =
|
||||
yield PlacesUtils.bookmarks.insert({ parentGuid: PlacesUtils.bookmarks.unfiledGuid,
|
||||
type: PlacesUtils.bookmarks.TYPE_FOLDER });
|
||||
checkBookmarkObject(folder_a);
|
||||
let folder_b =
|
||||
yield PlacesUtils.bookmarks.insert({ parentGuid: PlacesUtils.bookmarks.unfiledGuid,
|
||||
type: PlacesUtils.bookmarks.TYPE_FOLDER });
|
||||
checkBookmarkObject(folder_b);
|
||||
|
||||
/* folder_a: [sep_1, sep_2, sep_3], folder_b: [] */
|
||||
let sep_1 = yield PlacesUtils.bookmarks.insert({ parentGuid: folder_a.guid,
|
||||
type: PlacesUtils.bookmarks.TYPE_SEPARATOR });
|
||||
checkBookmarkObject(sep_1);
|
||||
let sep_2 = yield PlacesUtils.bookmarks.insert({ parentGuid: folder_a.guid,
|
||||
type: PlacesUtils.bookmarks.TYPE_SEPARATOR });
|
||||
checkBookmarkObject(sep_2);
|
||||
let sep_3 = yield PlacesUtils.bookmarks.insert({ parentGuid: folder_a.guid,
|
||||
type: PlacesUtils.bookmarks.TYPE_SEPARATOR });
|
||||
checkBookmarkObject(sep_3);
|
||||
|
||||
function ensurePosition(info, parentGuid, index) {
|
||||
checkBookmarkObject(info);
|
||||
Assert.equal(info.parentGuid, parentGuid);
|
||||
Assert.equal(info.index, index);
|
||||
}
|
||||
|
||||
// folder_a: [sep_2, sep_3, sep_1], folder_b: []
|
||||
sep_1.index = PlacesUtils.bookmarks.DEFAULT_INDEX;
|
||||
// Note sep_1 includes parentGuid even though we're not moving the item to
|
||||
// another folder
|
||||
sep_1 = yield PlacesUtils.bookmarks.update(sep_1);
|
||||
ensurePosition(sep_1, folder_a.guid, 2);
|
||||
sep_2 = yield PlacesUtils.bookmarks.fetch(sep_2.guid);
|
||||
ensurePosition(sep_2, folder_a.guid, 0);
|
||||
sep_3 = yield PlacesUtils.bookmarks.fetch(sep_3.guid);
|
||||
ensurePosition(sep_3, folder_a.guid, 1);
|
||||
sep_1 = yield PlacesUtils.bookmarks.fetch(sep_1.guid);
|
||||
ensurePosition(sep_1, folder_a.guid, 2);
|
||||
|
||||
// folder_a: [sep_2, sep_1], folder_b: [sep_3]
|
||||
sep_3.index = PlacesUtils.bookmarks.DEFAULT_INDEX;
|
||||
sep_3.parentGuid = folder_b.guid;
|
||||
sep_3 = yield PlacesUtils.bookmarks.update(sep_3);
|
||||
ensurePosition(sep_3, folder_b.guid, 0);
|
||||
sep_2 = yield PlacesUtils.bookmarks.fetch(sep_2.guid);
|
||||
ensurePosition(sep_2, folder_a.guid, 0);
|
||||
sep_1 = yield PlacesUtils.bookmarks.fetch(sep_1.guid);
|
||||
ensurePosition(sep_1, folder_a.guid, 1);
|
||||
sep_3 = yield PlacesUtils.bookmarks.fetch(sep_3.guid);
|
||||
ensurePosition(sep_3, folder_b.guid, 0);
|
||||
|
||||
// folder_a: [sep_1], folder_b: [sep_3, sep_2]
|
||||
sep_2.index = Number.MAX_SAFE_INTEGER;
|
||||
sep_2.parentGuid = folder_b.guid;
|
||||
sep_2 = yield PlacesUtils.bookmarks.update(sep_2);
|
||||
ensurePosition(sep_2, folder_b.guid, 1);
|
||||
sep_1 = yield PlacesUtils.bookmarks.fetch(sep_1.guid);
|
||||
ensurePosition(sep_1, folder_a.guid, 0);
|
||||
sep_3 = yield PlacesUtils.bookmarks.fetch(sep_3.guid);
|
||||
ensurePosition(sep_3, folder_b.guid, 0);
|
||||
sep_2 = yield PlacesUtils.bookmarks.fetch(sep_2.guid);
|
||||
ensurePosition(sep_2, folder_b.guid, 1);
|
||||
});
|
||||
|
||||
function run_test() {
|
||||
run_next_test();
|
||||
}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
|
||||
// Bug 1192692 - promiseBookmarksTree caches items without adding observers to
|
||||
// invalidate the cache.
|
||||
add_task(function* boookmarks_tree_cache() {
|
||||
// Note that for this test to be effective, it needs to use the "old" sync
|
||||
// bookmarks methods - using, eg, PlacesUtils.bookmarks.insert() doesn't
|
||||
// demonstrate the problem as it indirectly arranges for the observers to
|
||||
// be added.
|
||||
let id = PlacesUtils.bookmarks.insertBookmark(PlacesUtils.unfiledBookmarksFolderId,
|
||||
uri("http://example.com"),
|
||||
PlacesUtils.bookmarks.DEFAULT_INDEX,
|
||||
"A title");
|
||||
yield PlacesUtils.promiseBookmarksTree();
|
||||
|
||||
PlacesUtils.bookmarks.removeItem(id);
|
||||
|
||||
yield Assert.rejects(PlacesUtils.promiseItemGuid(id));
|
||||
});
|
||||
|
|
@ -0,0 +1,68 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim:set ts=2 sw=2 sts=2 et: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
// Get bookmark service
|
||||
var bmsvc = Cc["@mozilla.org/browser/nav-bookmarks-service;1"].
|
||||
getService(Ci.nsINavBookmarksService);
|
||||
|
||||
/**
|
||||
* Ensures that the Places APIs recognize that aBookmarkedUri is bookmarked
|
||||
* via aBookmarkId and that aUnbookmarkedUri is not bookmarked at all.
|
||||
*
|
||||
* @param aBookmarkId
|
||||
* an item ID whose corresponding URI is aBookmarkedUri
|
||||
* @param aBookmarkedUri
|
||||
* a bookmarked URI that has a corresponding item ID aBookmarkId
|
||||
* @param aUnbookmarkedUri
|
||||
* a URI that is not currently bookmarked at all
|
||||
*/
|
||||
function checkUris(aBookmarkId, aBookmarkedUri, aUnbookmarkedUri)
|
||||
{
|
||||
// Ensure that aBookmarkedUri equals some URI that is bookmarked
|
||||
var uri = bmsvc.getBookmarkedURIFor(aBookmarkedUri);
|
||||
do_check_neq(uri, null);
|
||||
do_check_true(uri.equals(aBookmarkedUri));
|
||||
|
||||
// Ensure that aBookmarkedUri is considered bookmarked
|
||||
do_check_true(bmsvc.isBookmarked(aBookmarkedUri));
|
||||
|
||||
// Ensure that the URI corresponding to aBookmarkId equals aBookmarkedUri
|
||||
do_check_true(bmsvc.getBookmarkURI(aBookmarkId).equals(aBookmarkedUri));
|
||||
|
||||
// Ensure that aUnbookmarkedUri does not equal any URI that is bookmarked
|
||||
uri = bmsvc.getBookmarkedURIFor(aUnbookmarkedUri);
|
||||
do_check_eq(uri, null);
|
||||
|
||||
// Ensure that aUnbookmarkedUri is not considered bookmarked
|
||||
do_check_false(bmsvc.isBookmarked(aUnbookmarkedUri));
|
||||
}
|
||||
|
||||
// main
|
||||
function run_test() {
|
||||
// Create a folder
|
||||
var folderId = bmsvc.createFolder(bmsvc.toolbarFolder,
|
||||
"test",
|
||||
bmsvc.DEFAULT_INDEX);
|
||||
|
||||
// Create 2 URIs
|
||||
var uri1 = uri("http://www.dogs.com");
|
||||
var uri2 = uri("http://www.cats.com");
|
||||
|
||||
// Bookmark the first one
|
||||
var bookmarkId = bmsvc.insertBookmark(folderId,
|
||||
uri1,
|
||||
bmsvc.DEFAULT_INDEX,
|
||||
"Dogs");
|
||||
|
||||
// uri1 is bookmarked via bookmarkId, uri2 is not
|
||||
checkUris(bookmarkId, uri1, uri2);
|
||||
|
||||
// Change the URI of the bookmark to uri2
|
||||
bmsvc.changeBookmarkURI(bookmarkId, uri2);
|
||||
|
||||
// uri2 is now bookmarked via bookmarkId, uri1 is not
|
||||
checkUris(bookmarkId, uri2, uri1);
|
||||
}
|
||||
|
|
@ -0,0 +1,84 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim:set ts=2 sw=2 sts=2 et: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/**
|
||||
* Test bookmarksService.getBookmarkedURIFor(aURI);
|
||||
*/
|
||||
|
||||
var hs = PlacesUtils.history;
|
||||
var bs = PlacesUtils.bookmarks;
|
||||
|
||||
function run_test() {
|
||||
run_next_test();
|
||||
}
|
||||
|
||||
add_task(function* test_getBookmarkedURIFor() {
|
||||
let now = Date.now() * 1000;
|
||||
const sourceURI = uri("http://test.mozilla.org/");
|
||||
// Add a visit and a bookmark.
|
||||
yield PlacesTestUtils.addVisits({ uri: sourceURI, visitDate: now });
|
||||
do_check_eq(bs.getBookmarkedURIFor(sourceURI), null);
|
||||
|
||||
let sourceItemId = bs.insertBookmark(bs.unfiledBookmarksFolder,
|
||||
sourceURI,
|
||||
bs.DEFAULT_INDEX,
|
||||
"bookmark");
|
||||
do_check_true(bs.getBookmarkedURIFor(sourceURI).equals(sourceURI));
|
||||
|
||||
// Add a redirected visit.
|
||||
const permaURI = uri("http://perma.mozilla.org/");
|
||||
yield PlacesTestUtils.addVisits({
|
||||
uri: permaURI,
|
||||
transition: TRANSITION_REDIRECT_PERMANENT,
|
||||
visitDate: now++,
|
||||
referrer: sourceURI
|
||||
});
|
||||
do_check_true(bs.getBookmarkedURIFor(sourceURI).equals(sourceURI));
|
||||
do_check_true(bs.getBookmarkedURIFor(permaURI).equals(sourceURI));
|
||||
// Add a bookmark to the destination.
|
||||
let permaItemId = bs.insertBookmark(bs.unfiledBookmarksFolder,
|
||||
permaURI,
|
||||
bs.DEFAULT_INDEX,
|
||||
"bookmark");
|
||||
do_check_true(bs.getBookmarkedURIFor(sourceURI).equals(sourceURI));
|
||||
do_check_true(bs.getBookmarkedURIFor(permaURI).equals(permaURI));
|
||||
// Now remove the bookmark on the destination.
|
||||
bs.removeItem(permaItemId);
|
||||
// We should see the source as bookmark.
|
||||
do_check_true(bs.getBookmarkedURIFor(permaURI).equals(sourceURI));
|
||||
|
||||
// Add another redirected visit.
|
||||
const tempURI = uri("http://perma.mozilla.org/");
|
||||
yield PlacesTestUtils.addVisits({
|
||||
uri: tempURI,
|
||||
transition: TRANSITION_REDIRECT_TEMPORARY,
|
||||
visitDate: now++,
|
||||
referrer: permaURI
|
||||
});
|
||||
|
||||
do_check_true(bs.getBookmarkedURIFor(sourceURI).equals(sourceURI));
|
||||
do_check_true(bs.getBookmarkedURIFor(tempURI).equals(sourceURI));
|
||||
// Add a bookmark to the destination.
|
||||
let tempItemId = bs.insertBookmark(bs.unfiledBookmarksFolder,
|
||||
tempURI,
|
||||
bs.DEFAULT_INDEX,
|
||||
"bookmark");
|
||||
do_check_true(bs.getBookmarkedURIFor(sourceURI).equals(sourceURI));
|
||||
do_check_true(bs.getBookmarkedURIFor(tempURI).equals(tempURI));
|
||||
|
||||
// Now remove the bookmark on the destination.
|
||||
bs.removeItem(tempItemId);
|
||||
// We should see the source as bookmark.
|
||||
do_check_true(bs.getBookmarkedURIFor(tempURI).equals(sourceURI));
|
||||
// Remove the source bookmark as well.
|
||||
bs.removeItem(sourceItemId);
|
||||
do_check_eq(bs.getBookmarkedURIFor(tempURI), null);
|
||||
|
||||
// Try to pass in a never seen URI, should return null and a new entry should
|
||||
// not be added to the database.
|
||||
do_check_eq(bs.getBookmarkedURIFor(uri("http://does.not.exist/")), null);
|
||||
do_check_false(page_in_database("http://does.not.exist/"));
|
||||
});
|
||||
310
toolkit/components/places/tests/bookmarks/test_keywords.js
Normal file
310
toolkit/components/places/tests/bookmarks/test_keywords.js
Normal file
|
|
@ -0,0 +1,310 @@
|
|||
const URI1 = NetUtil.newURI("http://test1.mozilla.org/");
|
||||
const URI2 = NetUtil.newURI("http://test2.mozilla.org/");
|
||||
const URI3 = NetUtil.newURI("http://test3.mozilla.org/");
|
||||
|
||||
function check_keyword(aURI, aKeyword) {
|
||||
if (aKeyword)
|
||||
aKeyword = aKeyword.toLowerCase();
|
||||
|
||||
for (let bm of PlacesUtils.getBookmarksForURI(aURI)) {
|
||||
let keyword = PlacesUtils.bookmarks.getKeywordForBookmark(bm);
|
||||
if (keyword && !aKeyword) {
|
||||
throw (`${aURI.spec} should not have a keyword`);
|
||||
} else if (aKeyword && keyword == aKeyword) {
|
||||
Assert.equal(keyword, aKeyword);
|
||||
}
|
||||
}
|
||||
|
||||
if (aKeyword) {
|
||||
let uri = PlacesUtils.bookmarks.getURIForKeyword(aKeyword);
|
||||
Assert.equal(uri.spec, aURI.spec);
|
||||
// Check case insensitivity.
|
||||
uri = PlacesUtils.bookmarks.getURIForKeyword(aKeyword.toUpperCase());
|
||||
Assert.equal(uri.spec, aURI.spec);
|
||||
}
|
||||
}
|
||||
|
||||
function* check_orphans() {
|
||||
let db = yield PlacesUtils.promiseDBConnection();
|
||||
let rows = yield db.executeCached(
|
||||
`SELECT id FROM moz_keywords k
|
||||
WHERE NOT EXISTS (SELECT 1 FROM moz_places WHERE id = k.place_id)
|
||||
`);
|
||||
Assert.equal(rows.length, 0);
|
||||
}
|
||||
|
||||
function expectNotifications() {
|
||||
let notifications = [];
|
||||
let observer = new Proxy(NavBookmarkObserver, {
|
||||
get(target, name) {
|
||||
if (name == "check") {
|
||||
PlacesUtils.bookmarks.removeObserver(observer);
|
||||
return expectedNotifications =>
|
||||
Assert.deepEqual(notifications, expectedNotifications);
|
||||
}
|
||||
|
||||
if (name.startsWith("onItemChanged")) {
|
||||
return function(id, prop, isAnno, val, lastMod, itemType, parentId, guid, parentGuid, oldVal) {
|
||||
if (prop != "keyword")
|
||||
return;
|
||||
let args = Array.from(arguments, arg => {
|
||||
if (arg && arg instanceof Ci.nsIURI)
|
||||
return new URL(arg.spec);
|
||||
if (arg && typeof(arg) == "number" && arg >= Date.now() * 1000)
|
||||
return new Date(parseInt(arg/1000));
|
||||
return arg;
|
||||
});
|
||||
notifications.push({ name: name, arguments: args });
|
||||
}
|
||||
}
|
||||
|
||||
return target[name];
|
||||
}
|
||||
});
|
||||
PlacesUtils.bookmarks.addObserver(observer, false);
|
||||
return observer;
|
||||
}
|
||||
|
||||
add_task(function test_invalid_input() {
|
||||
Assert.throws(() => PlacesUtils.bookmarks.getURIForKeyword(null),
|
||||
/NS_ERROR_ILLEGAL_VALUE/);
|
||||
Assert.throws(() => PlacesUtils.bookmarks.getURIForKeyword(""),
|
||||
/NS_ERROR_ILLEGAL_VALUE/);
|
||||
Assert.throws(() => PlacesUtils.bookmarks.getKeywordForBookmark(null),
|
||||
/NS_ERROR_ILLEGAL_VALUE/);
|
||||
Assert.throws(() => PlacesUtils.bookmarks.getKeywordForBookmark(0),
|
||||
/NS_ERROR_ILLEGAL_VALUE/);
|
||||
Assert.throws(() => PlacesUtils.bookmarks.setKeywordForBookmark(null, "k"),
|
||||
/NS_ERROR_ILLEGAL_VALUE/);
|
||||
Assert.throws(() => PlacesUtils.bookmarks.setKeywordForBookmark(0, "k"),
|
||||
/NS_ERROR_ILLEGAL_VALUE/);
|
||||
});
|
||||
|
||||
add_task(function* test_addBookmarkAndKeyword() {
|
||||
check_keyword(URI1, null);
|
||||
let fc = yield foreign_count(URI1);
|
||||
let observer = expectNotifications();
|
||||
|
||||
let itemId =
|
||||
PlacesUtils.bookmarks.insertBookmark(PlacesUtils.unfiledBookmarksFolderId,
|
||||
URI1,
|
||||
PlacesUtils.bookmarks.DEFAULT_INDEX,
|
||||
"test");
|
||||
|
||||
PlacesUtils.bookmarks.setKeywordForBookmark(itemId, "keyword");
|
||||
let bookmark = yield PlacesUtils.bookmarks.fetch({ url: URI1 });
|
||||
observer.check([ { name: "onItemChanged",
|
||||
arguments: [ itemId, "keyword", false, "keyword",
|
||||
bookmark.lastModified, bookmark.type,
|
||||
(yield PlacesUtils.promiseItemId(bookmark.parentGuid)),
|
||||
bookmark.guid, bookmark.parentGuid, "",
|
||||
Ci.nsINavBookmarksService.SOURCE_DEFAULT ] }
|
||||
]);
|
||||
yield PlacesTestUtils.promiseAsyncUpdates();
|
||||
|
||||
check_keyword(URI1, "keyword");
|
||||
Assert.equal((yield foreign_count(URI1)), fc + 2); // + 1 bookmark + 1 keyword
|
||||
|
||||
yield PlacesTestUtils.promiseAsyncUpdates();
|
||||
yield check_orphans();
|
||||
});
|
||||
|
||||
add_task(function* test_addBookmarkToURIHavingKeyword() {
|
||||
// The uri has already a keyword.
|
||||
check_keyword(URI1, "keyword");
|
||||
let fc = yield foreign_count(URI1);
|
||||
|
||||
let itemId =
|
||||
PlacesUtils.bookmarks.insertBookmark(PlacesUtils.unfiledBookmarksFolderId,
|
||||
URI1,
|
||||
PlacesUtils.bookmarks.DEFAULT_INDEX,
|
||||
"test");
|
||||
check_keyword(URI1, "keyword");
|
||||
Assert.equal((yield foreign_count(URI1)), fc + 1); // + 1 bookmark
|
||||
|
||||
PlacesUtils.bookmarks.removeItem(itemId);
|
||||
yield PlacesTestUtils.promiseAsyncUpdates();
|
||||
check_orphans();
|
||||
});
|
||||
|
||||
add_task(function* test_sameKeywordDifferentURI() {
|
||||
let fc1 = yield foreign_count(URI1);
|
||||
let fc2 = yield foreign_count(URI2);
|
||||
let observer = expectNotifications();
|
||||
|
||||
let itemId =
|
||||
PlacesUtils.bookmarks.insertBookmark(PlacesUtils.unfiledBookmarksFolderId,
|
||||
URI2,
|
||||
PlacesUtils.bookmarks.DEFAULT_INDEX,
|
||||
"test2");
|
||||
check_keyword(URI1, "keyword");
|
||||
check_keyword(URI2, null);
|
||||
|
||||
PlacesUtils.bookmarks.setKeywordForBookmark(itemId, "kEyWoRd");
|
||||
|
||||
let bookmark1 = yield PlacesUtils.bookmarks.fetch({ url: URI1 });
|
||||
let bookmark2 = yield PlacesUtils.bookmarks.fetch({ url: URI2 });
|
||||
observer.check([ { name: "onItemChanged",
|
||||
arguments: [ (yield PlacesUtils.promiseItemId(bookmark1.guid)),
|
||||
"keyword", false, "",
|
||||
bookmark1.lastModified, bookmark1.type,
|
||||
(yield PlacesUtils.promiseItemId(bookmark1.parentGuid)),
|
||||
bookmark1.guid, bookmark1.parentGuid, "",
|
||||
Ci.nsINavBookmarksService.SOURCE_DEFAULT ] },
|
||||
{ name: "onItemChanged",
|
||||
arguments: [ itemId, "keyword", false, "keyword",
|
||||
bookmark2.lastModified, bookmark2.type,
|
||||
(yield PlacesUtils.promiseItemId(bookmark2.parentGuid)),
|
||||
bookmark2.guid, bookmark2.parentGuid, "",
|
||||
Ci.nsINavBookmarksService.SOURCE_DEFAULT ] }
|
||||
]);
|
||||
yield PlacesTestUtils.promiseAsyncUpdates();
|
||||
|
||||
// The keyword should have been "moved" to the new URI.
|
||||
check_keyword(URI1, null);
|
||||
Assert.equal((yield foreign_count(URI1)), fc1 - 1); // - 1 keyword
|
||||
check_keyword(URI2, "keyword");
|
||||
Assert.equal((yield foreign_count(URI2)), fc2 + 2); // + 1 bookmark + 1 keyword
|
||||
|
||||
yield PlacesTestUtils.promiseAsyncUpdates();
|
||||
check_orphans();
|
||||
});
|
||||
|
||||
add_task(function* test_sameURIDifferentKeyword() {
|
||||
let fc = yield foreign_count(URI2);
|
||||
let observer = expectNotifications();
|
||||
|
||||
let itemId =
|
||||
PlacesUtils.bookmarks.insertBookmark(PlacesUtils.unfiledBookmarksFolderId,
|
||||
URI2,
|
||||
PlacesUtils.bookmarks.DEFAULT_INDEX,
|
||||
"test2");
|
||||
check_keyword(URI2, "keyword");
|
||||
|
||||
PlacesUtils.bookmarks.setKeywordForBookmark(itemId, "keyword2");
|
||||
|
||||
let bookmarks = [];
|
||||
yield PlacesUtils.bookmarks.fetch({ url: URI2 }, bookmark => bookmarks.push(bookmark));
|
||||
observer.check([ { name: "onItemChanged",
|
||||
arguments: [ (yield PlacesUtils.promiseItemId(bookmarks[0].guid)),
|
||||
"keyword", false, "keyword2",
|
||||
bookmarks[0].lastModified, bookmarks[0].type,
|
||||
(yield PlacesUtils.promiseItemId(bookmarks[0].parentGuid)),
|
||||
bookmarks[0].guid, bookmarks[0].parentGuid, "",
|
||||
Ci.nsINavBookmarksService.SOURCE_DEFAULT ] },
|
||||
{ name: "onItemChanged",
|
||||
arguments: [ (yield PlacesUtils.promiseItemId(bookmarks[1].guid)),
|
||||
"keyword", false, "keyword2",
|
||||
bookmarks[1].lastModified, bookmarks[1].type,
|
||||
(yield PlacesUtils.promiseItemId(bookmarks[1].parentGuid)),
|
||||
bookmarks[1].guid, bookmarks[1].parentGuid, "",
|
||||
Ci.nsINavBookmarksService.SOURCE_DEFAULT ] }
|
||||
]);
|
||||
yield PlacesTestUtils.promiseAsyncUpdates();
|
||||
|
||||
check_keyword(URI2, "keyword2");
|
||||
Assert.equal((yield foreign_count(URI2)), fc + 2); // + 1 bookmark + 1 keyword
|
||||
|
||||
yield PlacesTestUtils.promiseAsyncUpdates();
|
||||
check_orphans();
|
||||
});
|
||||
|
||||
add_task(function* test_removeBookmarkWithKeyword() {
|
||||
let fc = yield foreign_count(URI2);
|
||||
let itemId =
|
||||
PlacesUtils.bookmarks.insertBookmark(PlacesUtils.unfiledBookmarksFolderId,
|
||||
URI2,
|
||||
PlacesUtils.bookmarks.DEFAULT_INDEX,
|
||||
"test");
|
||||
|
||||
// The keyword should not be removed, since there are other bookmarks yet.
|
||||
PlacesUtils.bookmarks.removeItem(itemId);
|
||||
|
||||
check_keyword(URI2, "keyword2");
|
||||
Assert.equal((yield foreign_count(URI2)), fc); // + 1 bookmark - 1 bookmark
|
||||
|
||||
yield PlacesTestUtils.promiseAsyncUpdates();
|
||||
check_orphans();
|
||||
});
|
||||
|
||||
add_task(function* test_unsetKeyword() {
|
||||
let fc = yield foreign_count(URI2);
|
||||
let observer = expectNotifications();
|
||||
|
||||
let itemId =
|
||||
PlacesUtils.bookmarks.insertBookmark(PlacesUtils.unfiledBookmarksFolderId,
|
||||
URI2,
|
||||
PlacesUtils.bookmarks.DEFAULT_INDEX,
|
||||
"test");
|
||||
|
||||
// The keyword should be removed from any bookmark.
|
||||
PlacesUtils.bookmarks.setKeywordForBookmark(itemId, null);
|
||||
|
||||
let bookmarks = [];
|
||||
yield PlacesUtils.bookmarks.fetch({ url: URI2 }, bookmark => bookmarks.push(bookmark));
|
||||
do_print(bookmarks.length);
|
||||
observer.check([ { name: "onItemChanged",
|
||||
arguments: [ (yield PlacesUtils.promiseItemId(bookmarks[0].guid)),
|
||||
"keyword", false, "",
|
||||
bookmarks[0].lastModified, bookmarks[0].type,
|
||||
(yield PlacesUtils.promiseItemId(bookmarks[0].parentGuid)),
|
||||
bookmarks[0].guid, bookmarks[0].parentGuid, "",
|
||||
Ci.nsINavBookmarksService.SOURCE_DEFAULT ] },
|
||||
{ name: "onItemChanged",
|
||||
arguments: [ (yield PlacesUtils.promiseItemId(bookmarks[1].guid)),
|
||||
"keyword", false, "",
|
||||
bookmarks[1].lastModified, bookmarks[1].type,
|
||||
(yield PlacesUtils.promiseItemId(bookmarks[1].parentGuid)),
|
||||
bookmarks[1].guid, bookmarks[1].parentGuid, "",
|
||||
Ci.nsINavBookmarksService.SOURCE_DEFAULT ] },
|
||||
{ name: "onItemChanged",
|
||||
arguments: [ (yield PlacesUtils.promiseItemId(bookmarks[2].guid)),
|
||||
"keyword", false, "",
|
||||
bookmarks[2].lastModified, bookmarks[2].type,
|
||||
(yield PlacesUtils.promiseItemId(bookmarks[2].parentGuid)),
|
||||
bookmarks[2].guid, bookmarks[2].parentGuid, "",
|
||||
Ci.nsINavBookmarksService.SOURCE_DEFAULT ] }
|
||||
]);
|
||||
|
||||
check_keyword(URI1, null);
|
||||
check_keyword(URI2, null);
|
||||
Assert.equal((yield foreign_count(URI2)), fc - 1); // + 1 bookmark - 2 keyword
|
||||
|
||||
yield PlacesTestUtils.promiseAsyncUpdates();
|
||||
check_orphans();
|
||||
});
|
||||
|
||||
add_task(function* test_addRemoveBookmark() {
|
||||
let observer = expectNotifications();
|
||||
|
||||
let itemId =
|
||||
PlacesUtils.bookmarks.insertBookmark(PlacesUtils.unfiledBookmarksFolderId,
|
||||
URI3,
|
||||
PlacesUtils.bookmarks.DEFAULT_INDEX,
|
||||
"test3");
|
||||
|
||||
PlacesUtils.bookmarks.setKeywordForBookmark(itemId, "keyword");
|
||||
let bookmark = yield PlacesUtils.bookmarks.fetch({ url: URI3 });
|
||||
let parentId = yield PlacesUtils.promiseItemId(bookmark.parentGuid);
|
||||
PlacesUtils.bookmarks.removeItem(itemId);
|
||||
|
||||
observer.check([ { name: "onItemChanged",
|
||||
arguments: [ itemId,
|
||||
"keyword", false, "keyword",
|
||||
bookmark.lastModified, bookmark.type,
|
||||
parentId,
|
||||
bookmark.guid, bookmark.parentGuid, "",
|
||||
Ci.nsINavBookmarksService.SOURCE_DEFAULT ] }
|
||||
]);
|
||||
|
||||
check_keyword(URI3, null);
|
||||
// Don't check the foreign count since the process is async.
|
||||
// The new test_keywords.js in unit is checking this though.
|
||||
|
||||
yield PlacesTestUtils.promiseAsyncUpdates();
|
||||
check_orphans();
|
||||
});
|
||||
|
||||
function run_test() {
|
||||
run_next_test();
|
||||
}
|
||||
|
|
@ -0,0 +1,640 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
// Tests that each nsINavBookmarksObserver method gets the correct input.
|
||||
Cu.import("resource://gre/modules/PromiseUtils.jsm");
|
||||
|
||||
const GUID_RE = /^[a-zA-Z0-9\-_]{12}$/;
|
||||
|
||||
var gBookmarksObserver = {
|
||||
expected: [],
|
||||
setup(expected) {
|
||||
this.expected = expected;
|
||||
this.deferred = PromiseUtils.defer();
|
||||
return this.deferred.promise;
|
||||
},
|
||||
validate: function (aMethodName, aArguments) {
|
||||
do_check_eq(this.expected[0].name, aMethodName);
|
||||
|
||||
let args = this.expected.shift().args;
|
||||
do_check_eq(aArguments.length, args.length);
|
||||
for (let i = 0; i < aArguments.length; i++) {
|
||||
do_check_true(args[i].check(aArguments[i]), aMethodName + "(args[" + i + "]: " + args[i].name + ")");
|
||||
}
|
||||
|
||||
if (this.expected.length === 0) {
|
||||
this.deferred.resolve();
|
||||
}
|
||||
},
|
||||
|
||||
// nsINavBookmarkObserver
|
||||
onBeginUpdateBatch() {
|
||||
return this.validate("onBeginUpdateBatch", arguments);
|
||||
},
|
||||
onEndUpdateBatch() {
|
||||
return this.validate("onEndUpdateBatch", arguments);
|
||||
},
|
||||
onItemAdded() {
|
||||
return this.validate("onItemAdded", arguments);
|
||||
},
|
||||
onItemRemoved() {
|
||||
return this.validate("onItemRemoved", arguments);
|
||||
},
|
||||
onItemChanged() {
|
||||
return this.validate("onItemChanged", arguments);
|
||||
},
|
||||
onItemVisited() {
|
||||
return this.validate("onItemVisited", arguments);
|
||||
},
|
||||
onItemMoved() {
|
||||
return this.validate("onItemMoved", arguments);
|
||||
},
|
||||
|
||||
// nsISupports
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsINavBookmarkObserver]),
|
||||
};
|
||||
|
||||
var gBookmarkSkipObserver = {
|
||||
skipTags: true,
|
||||
skipDescendantsOnItemRemoval: true,
|
||||
|
||||
expected: null,
|
||||
setup(expected) {
|
||||
this.expected = expected;
|
||||
this.deferred = PromiseUtils.defer();
|
||||
return this.deferred.promise;
|
||||
},
|
||||
validate: function (aMethodName) {
|
||||
do_check_eq(this.expected.shift(), aMethodName);
|
||||
if (this.expected.length === 0) {
|
||||
this.deferred.resolve();
|
||||
}
|
||||
},
|
||||
|
||||
// nsINavBookmarkObserver
|
||||
onBeginUpdateBatch() {
|
||||
return this.validate("onBeginUpdateBatch", arguments);
|
||||
},
|
||||
onEndUpdateBatch() {
|
||||
return this.validate("onEndUpdateBatch", arguments);
|
||||
},
|
||||
onItemAdded() {
|
||||
return this.validate("onItemAdded", arguments);
|
||||
},
|
||||
onItemRemoved() {
|
||||
return this.validate("onItemRemoved", arguments);
|
||||
},
|
||||
onItemChanged() {
|
||||
return this.validate("onItemChanged", arguments);
|
||||
},
|
||||
onItemVisited() {
|
||||
return this.validate("onItemVisited", arguments);
|
||||
},
|
||||
onItemMoved() {
|
||||
return this.validate("onItemMoved", arguments);
|
||||
},
|
||||
|
||||
// nsISupports
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsINavBookmarkObserver]),
|
||||
};
|
||||
|
||||
|
||||
add_task(function setup() {
|
||||
PlacesUtils.bookmarks.addObserver(gBookmarksObserver, false);
|
||||
PlacesUtils.bookmarks.addObserver(gBookmarkSkipObserver, false);
|
||||
});
|
||||
|
||||
add_task(function* batch() {
|
||||
let promise = Promise.all([
|
||||
gBookmarksObserver.setup([
|
||||
{ name: "onBeginUpdateBatch",
|
||||
args: [] },
|
||||
{ name: "onEndUpdateBatch",
|
||||
args: [] },
|
||||
]),
|
||||
gBookmarkSkipObserver.setup([
|
||||
"onBeginUpdateBatch", "onEndUpdateBatch"
|
||||
])]);
|
||||
PlacesUtils.bookmarks.runInBatchMode({
|
||||
runBatched: function () {
|
||||
// Nothing.
|
||||
}
|
||||
}, null);
|
||||
yield promise;
|
||||
});
|
||||
|
||||
add_task(function* onItemAdded_bookmark() {
|
||||
const TITLE = "Bookmark 1";
|
||||
let uri = NetUtil.newURI("http://1.mozilla.org/");
|
||||
let promise = Promise.all([
|
||||
gBookmarkSkipObserver.setup([
|
||||
"onItemAdded"
|
||||
]),
|
||||
gBookmarksObserver.setup([
|
||||
{ name: "onItemAdded",
|
||||
args: [
|
||||
{ name: "itemId", check: v => typeof(v) == "number" && v > 0 },
|
||||
{ name: "parentId", check: v => v === PlacesUtils.unfiledBookmarksFolderId },
|
||||
{ name: "index", check: v => v === 0 },
|
||||
{ name: "itemType", check: v => v === PlacesUtils.bookmarks.TYPE_BOOKMARK },
|
||||
{ name: "uri", check: v => v instanceof Ci.nsIURI && v.equals(uri) },
|
||||
{ name: "title", check: v => v === TITLE },
|
||||
{ name: "dateAdded", check: v => typeof(v) == "number" && v > 0 },
|
||||
{ name: "guid", check: v => typeof(v) == "string" && GUID_RE.test(v) },
|
||||
{ name: "parentGuid", check: v => typeof(v) == "string" && GUID_RE.test(v) },
|
||||
{ name: "source", check: v => Object.values(PlacesUtils.bookmarks.SOURCES).includes(v) },
|
||||
] },
|
||||
])]);
|
||||
PlacesUtils.bookmarks.insertBookmark(PlacesUtils.unfiledBookmarksFolderId,
|
||||
uri, PlacesUtils.bookmarks.DEFAULT_INDEX,
|
||||
TITLE);
|
||||
yield promise;
|
||||
});
|
||||
|
||||
add_task(function* onItemAdded_separator() {
|
||||
let promise = Promise.all([
|
||||
gBookmarkSkipObserver.setup([
|
||||
"onItemAdded"
|
||||
]),
|
||||
gBookmarksObserver.setup([
|
||||
{ name: "onItemAdded",
|
||||
args: [
|
||||
{ name: "itemId", check: v => typeof(v) == "number" && v > 0 },
|
||||
{ name: "parentId", check: v => v === PlacesUtils.unfiledBookmarksFolderId },
|
||||
{ name: "index", check: v => v === 1 },
|
||||
{ name: "itemType", check: v => v === PlacesUtils.bookmarks.TYPE_SEPARATOR },
|
||||
{ name: "uri", check: v => v === null },
|
||||
{ name: "title", check: v => v === null },
|
||||
{ name: "dateAdded", check: v => typeof(v) == "number" && v > 0 },
|
||||
{ name: "guid", check: v => typeof(v) == "string" && GUID_RE.test(v) },
|
||||
{ name: "parentGuid", check: v => typeof(v) == "string" && GUID_RE.test(v) },
|
||||
{ name: "source", check: v => Object.values(PlacesUtils.bookmarks.SOURCES).includes(v) },
|
||||
] },
|
||||
])]);
|
||||
PlacesUtils.bookmarks.insertSeparator(PlacesUtils.unfiledBookmarksFolderId,
|
||||
PlacesUtils.bookmarks.DEFAULT_INDEX);
|
||||
yield promise;
|
||||
});
|
||||
|
||||
add_task(function* onItemAdded_folder() {
|
||||
const TITLE = "Folder 1";
|
||||
let promise = Promise.all([
|
||||
gBookmarkSkipObserver.setup([
|
||||
"onItemAdded"
|
||||
]),
|
||||
gBookmarksObserver.setup([
|
||||
{ name: "onItemAdded",
|
||||
args: [
|
||||
{ name: "itemId", check: v => typeof(v) == "number" && v > 0 },
|
||||
{ name: "parentId", check: v => v === PlacesUtils.unfiledBookmarksFolderId },
|
||||
{ name: "index", check: v => v === 2 },
|
||||
{ name: "itemType", check: v => v === PlacesUtils.bookmarks.TYPE_FOLDER },
|
||||
{ name: "uri", check: v => v === null },
|
||||
{ name: "title", check: v => v === TITLE },
|
||||
{ name: "dateAdded", check: v => typeof(v) == "number" && v > 0 },
|
||||
{ name: "guid", check: v => typeof(v) == "string" && GUID_RE.test(v) },
|
||||
{ name: "parentGuid", check: v => typeof(v) == "string" && GUID_RE.test(v) },
|
||||
{ name: "source", check: v => Object.values(PlacesUtils.bookmarks.SOURCES).includes(v) },
|
||||
] },
|
||||
])]);
|
||||
PlacesUtils.bookmarks.createFolder(PlacesUtils.unfiledBookmarksFolderId,
|
||||
TITLE,
|
||||
PlacesUtils.bookmarks.DEFAULT_INDEX);
|
||||
yield promise;
|
||||
});
|
||||
|
||||
add_task(function* onItemChanged_title_bookmark() {
|
||||
let id = PlacesUtils.bookmarks.getIdForItemAt(PlacesUtils.unfiledBookmarksFolderId, 0);
|
||||
const TITLE = "New title";
|
||||
let promise = Promise.all([
|
||||
gBookmarkSkipObserver.setup([
|
||||
"onItemChanged"
|
||||
]),
|
||||
gBookmarksObserver.setup([
|
||||
{ name: "onItemChanged", // This is an unfortunate effect of bug 653910.
|
||||
args: [
|
||||
{ name: "itemId", check: v => typeof(v) == "number" && v > 0 },
|
||||
{ name: "property", check: v => v === "title" },
|
||||
{ name: "isAnno", check: v => v === false },
|
||||
{ name: "newValue", check: v => v === TITLE },
|
||||
{ name: "lastModified", check: v => typeof(v) == "number" && v > 0 },
|
||||
{ name: "itemType", check: v => v === PlacesUtils.bookmarks.TYPE_BOOKMARK },
|
||||
{ name: "parentId", check: v => v === PlacesUtils.unfiledBookmarksFolderId },
|
||||
{ name: "guid", check: v => typeof(v) == "string" && GUID_RE.test(v) },
|
||||
{ name: "parentGuid", check: v => typeof(v) == "string" && GUID_RE.test(v) },
|
||||
{ name: "oldValue", check: v => typeof(v) == "string" },
|
||||
{ name: "source", check: v => Object.values(PlacesUtils.bookmarks.SOURCES).includes(v) },
|
||||
] },
|
||||
])]);
|
||||
PlacesUtils.bookmarks.setItemTitle(id, TITLE);
|
||||
yield promise;
|
||||
});
|
||||
|
||||
add_task(function* onItemChanged_tags_bookmark() {
|
||||
let id = PlacesUtils.bookmarks.getIdForItemAt(PlacesUtils.unfiledBookmarksFolderId, 0);
|
||||
let uri = PlacesUtils.bookmarks.getBookmarkURI(id);
|
||||
const TAG = "tag";
|
||||
let promise = Promise.all([
|
||||
gBookmarkSkipObserver.setup([
|
||||
"onItemChanged", "onItemChanged"
|
||||
]),
|
||||
gBookmarksObserver.setup([
|
||||
{ name: "onItemAdded", // This is the tag folder.
|
||||
args: [
|
||||
{ name: "itemId", check: v => typeof(v) == "number" && v > 0 },
|
||||
{ name: "parentId", check: v => v === PlacesUtils.tagsFolderId },
|
||||
{ name: "index", check: v => v === 0 },
|
||||
{ name: "itemType", check: v => v === PlacesUtils.bookmarks.TYPE_FOLDER },
|
||||
{ name: "uri", check: v => v === null },
|
||||
{ name: "title", check: v => v === TAG },
|
||||
{ name: "dateAdded", check: v => typeof(v) == "number" && v > 0 },
|
||||
{ name: "guid", check: v => typeof(v) == "string" && GUID_RE.test(v) },
|
||||
{ name: "parentGuid", check: v => typeof(v) == "string" && GUID_RE.test(v) },
|
||||
{ name: "source", check: v => Object.values(PlacesUtils.bookmarks.SOURCES).includes(v) },
|
||||
] },
|
||||
{ name: "onItemAdded", // This is the tag.
|
||||
args: [
|
||||
{ name: "itemId", check: v => typeof(v) == "number" && v > 0 },
|
||||
{ name: "parentId", check: v => typeof(v) == "number" && v > 0 },
|
||||
{ name: "index", check: v => v === 0 },
|
||||
{ name: "itemType", check: v => v === PlacesUtils.bookmarks.TYPE_BOOKMARK },
|
||||
{ name: "uri", check: v => v instanceof Ci.nsIURI && v.equals(uri) },
|
||||
{ name: "title", check: v => v === null },
|
||||
{ name: "dateAdded", check: v => typeof(v) == "number" && v > 0 },
|
||||
{ name: "guid", check: v => typeof(v) == "string" && GUID_RE.test(v) },
|
||||
{ name: "parentGuid", check: v => typeof(v) == "string" && GUID_RE.test(v) },
|
||||
{ name: "source", check: v => Object.values(PlacesUtils.bookmarks.SOURCES).includes(v) },
|
||||
] },
|
||||
{ name: "onItemChanged",
|
||||
args: [
|
||||
{ name: "itemId", check: v => typeof(v) == "number" && v > 0 },
|
||||
{ name: "property", check: v => v === "tags" },
|
||||
{ name: "isAnno", check: v => v === false },
|
||||
{ name: "newValue", check: v => v === "" },
|
||||
{ name: "lastModified", check: v => typeof(v) == "number" && v > 0 },
|
||||
{ name: "itemType", check: v => v === PlacesUtils.bookmarks.TYPE_BOOKMARK },
|
||||
{ name: "parentId", check: v => v === PlacesUtils.unfiledBookmarksFolderId },
|
||||
{ name: "guid", check: v => typeof(v) == "string" && GUID_RE.test(v) },
|
||||
{ name: "parentGuid", check: v => typeof(v) == "string" && GUID_RE.test(v) },
|
||||
{ name: "oldValue", check: v => typeof(v) == "string" },
|
||||
{ name: "source", check: v => Object.values(PlacesUtils.bookmarks.SOURCES).includes(v) },
|
||||
] },
|
||||
{ name: "onItemRemoved", // This is the tag.
|
||||
args: [
|
||||
{ name: "itemId", check: v => typeof(v) == "number" && v > 0 },
|
||||
{ name: "parentId", check: v => typeof(v) == "number" && v > 0 },
|
||||
{ name: "index", check: v => v === 0 },
|
||||
{ name: "itemType", check: v => v === PlacesUtils.bookmarks.TYPE_BOOKMARK },
|
||||
{ name: "uri", check: v => v instanceof Ci.nsIURI && v.equals(uri) },
|
||||
{ name: "guid", check: v => typeof(v) == "string" && GUID_RE.test(v) },
|
||||
{ name: "parentGuid", check: v => typeof(v) == "string" && GUID_RE.test(v) },
|
||||
{ name: "source", check: v => Object.values(PlacesUtils.bookmarks.SOURCES).includes(v) },
|
||||
] },
|
||||
{ name: "onItemRemoved", // This is the tag folder.
|
||||
args: [
|
||||
{ name: "itemId", check: v => typeof(v) == "number" && v > 0 },
|
||||
{ name: "parentId", check: v => v === PlacesUtils.tagsFolderId },
|
||||
{ name: "index", check: v => v === 0 },
|
||||
{ name: "itemType", check: v => v === PlacesUtils.bookmarks.TYPE_FOLDER },
|
||||
{ name: "uri", check: v => v === null },
|
||||
{ name: "guid", check: v => typeof(v) == "string" && GUID_RE.test(v) },
|
||||
{ name: "parentGuid", check: v => typeof(v) == "string" && GUID_RE.test(v) },
|
||||
{ name: "source", check: v => Object.values(PlacesUtils.bookmarks.SOURCES).includes(v) },
|
||||
] },
|
||||
{ name: "onItemChanged",
|
||||
args: [
|
||||
{ name: "itemId", check: v => typeof(v) == "number" && v > 0 },
|
||||
{ name: "property", check: v => v === "tags" },
|
||||
{ name: "isAnno", check: v => v === false },
|
||||
{ name: "newValue", check: v => v === "" },
|
||||
{ name: "lastModified", check: v => typeof(v) == "number" && v > 0 },
|
||||
{ name: "itemType", check: v => v === PlacesUtils.bookmarks.TYPE_BOOKMARK },
|
||||
{ name: "parentId", check: v => v === PlacesUtils.unfiledBookmarksFolderId },
|
||||
{ name: "guid", check: v => typeof(v) == "string" && GUID_RE.test(v) },
|
||||
{ name: "parentGuid", check: v => typeof(v) == "string" && GUID_RE.test(v) },
|
||||
{ name: "oldValue", check: v => typeof(v) == "string" },
|
||||
{ name: "source", check: v => Object.values(PlacesUtils.bookmarks.SOURCES).includes(v) },
|
||||
] },
|
||||
])]);
|
||||
PlacesUtils.tagging.tagURI(uri, [TAG]);
|
||||
PlacesUtils.tagging.untagURI(uri, [TAG]);
|
||||
yield promise;
|
||||
});
|
||||
|
||||
add_task(function* onItemMoved_bookmark() {
|
||||
let id = PlacesUtils.bookmarks.getIdForItemAt(PlacesUtils.unfiledBookmarksFolderId, 0);
|
||||
let promise = Promise.all([
|
||||
gBookmarkSkipObserver.setup([
|
||||
"onItemMoved", "onItemMoved"
|
||||
]),
|
||||
gBookmarksObserver.setup([
|
||||
{ name: "onItemMoved",
|
||||
args: [
|
||||
{ name: "itemId", check: v => typeof(v) == "number" && v > 0 },
|
||||
{ name: "oldParentId", check: v => v === PlacesUtils.unfiledBookmarksFolderId },
|
||||
{ name: "oldIndex", check: v => v === 0 },
|
||||
{ name: "newParentId", check: v => v === PlacesUtils.toolbarFolderId },
|
||||
{ name: "newIndex", check: v => v === 0 },
|
||||
{ name: "itemType", check: v => v === PlacesUtils.bookmarks.TYPE_BOOKMARK },
|
||||
{ name: "guid", check: v => typeof(v) == "string" && GUID_RE.test(v) },
|
||||
{ name: "oldParentGuid", check: v => typeof(v) == "string" && GUID_RE.test(v) },
|
||||
{ name: "newParentGuid", check: v => typeof(v) == "string" && GUID_RE.test(v) },
|
||||
{ name: "source", check: v => Object.values(PlacesUtils.bookmarks.SOURCES).includes(v) },
|
||||
] },
|
||||
{ name: "onItemMoved",
|
||||
args: [
|
||||
{ name: "itemId", check: v => typeof(v) == "number" && v > 0 },
|
||||
{ name: "oldParentId", check: v => v === PlacesUtils.toolbarFolderId },
|
||||
{ name: "oldIndex", check: v => v === 0 },
|
||||
{ name: "newParentId", check: v => v === PlacesUtils.unfiledBookmarksFolderId },
|
||||
{ name: "newIndex", check: v => v === 0 },
|
||||
{ name: "itemType", check: v => v === PlacesUtils.bookmarks.TYPE_BOOKMARK },
|
||||
{ name: "guid", check: v => typeof(v) == "string" && GUID_RE.test(v) },
|
||||
{ name: "oldParentGuid", check: v => typeof(v) == "string" && GUID_RE.test(v) },
|
||||
{ name: "newParentGuid", check: v => typeof(v) == "string" && GUID_RE.test(v) },
|
||||
{ name: "source", check: v => Object.values(PlacesUtils.bookmarks.SOURCES).includes(v) },
|
||||
] },
|
||||
])]);
|
||||
PlacesUtils.bookmarks.moveItem(id, PlacesUtils.toolbarFolderId, 0);
|
||||
PlacesUtils.bookmarks.moveItem(id, PlacesUtils.unfiledBookmarksFolderId, 0);
|
||||
yield promise;
|
||||
});
|
||||
|
||||
add_task(function* onItemMoved_bookmark() {
|
||||
let id = PlacesUtils.bookmarks.getIdForItemAt(PlacesUtils.unfiledBookmarksFolderId, 0);
|
||||
let uri = PlacesUtils.bookmarks.getBookmarkURI(id);
|
||||
let promise = Promise.all([
|
||||
gBookmarkSkipObserver.setup([
|
||||
"onItemVisited"
|
||||
]),
|
||||
gBookmarksObserver.setup([
|
||||
{ name: "onItemVisited",
|
||||
args: [
|
||||
{ name: "itemId", check: v => typeof(v) == "number" && v > 0 },
|
||||
{ name: "visitId", check: v => typeof(v) == "number" && v > 0 },
|
||||
{ name: "time", check: v => typeof(v) == "number" && v > 0 },
|
||||
{ name: "transitionType", check: v => v === PlacesUtils.history.TRANSITION_TYPED },
|
||||
{ name: "uri", check: v => v instanceof Ci.nsIURI && v.equals(uri) },
|
||||
{ name: "parentId", check: v => v === PlacesUtils.unfiledBookmarksFolderId },
|
||||
{ name: "guid", check: v => typeof(v) == "string" && GUID_RE.test(v) },
|
||||
{ name: "parentGuid", check: v => typeof(v) == "string" && GUID_RE.test(v) },
|
||||
] },
|
||||
])]);
|
||||
PlacesTestUtils.addVisits({ uri: uri, transition: TRANSITION_TYPED });
|
||||
yield promise;
|
||||
});
|
||||
|
||||
add_task(function* onItemRemoved_bookmark() {
|
||||
let id = PlacesUtils.bookmarks.getIdForItemAt(PlacesUtils.unfiledBookmarksFolderId, 0);
|
||||
let uri = PlacesUtils.bookmarks.getBookmarkURI(id);
|
||||
let promise = Promise.all([
|
||||
gBookmarkSkipObserver.setup([
|
||||
"onItemChanged", "onItemRemoved"
|
||||
]),
|
||||
gBookmarksObserver.setup([
|
||||
{ name: "onItemChanged", // This is an unfortunate effect of bug 653910.
|
||||
args: [
|
||||
{ name: "itemId", check: v => typeof(v) == "number" && v > 0 },
|
||||
{ name: "property", check: v => v === "" },
|
||||
{ name: "isAnno", check: v => v === true },
|
||||
{ name: "newValue", check: v => v === "" },
|
||||
{ name: "lastModified", check: v => typeof(v) == "number" && v > 0 },
|
||||
{ name: "itemType", check: v => v === PlacesUtils.bookmarks.TYPE_BOOKMARK },
|
||||
{ name: "parentId", check: v => v === PlacesUtils.unfiledBookmarksFolderId },
|
||||
{ name: "guid", check: v => typeof(v) == "string" && GUID_RE.test(v) },
|
||||
{ name: "parentGuid", check: v => typeof(v) == "string" && GUID_RE.test(v) },
|
||||
{ name: "oldValue", check: v => typeof(v) == "string" },
|
||||
{ name: "source", check: v => Object.values(PlacesUtils.bookmarks.SOURCES).includes(v) },
|
||||
] },
|
||||
{ name: "onItemRemoved",
|
||||
args: [
|
||||
{ name: "itemId", check: v => typeof(v) == "number" && v > 0 },
|
||||
{ name: "parentId", check: v => v === PlacesUtils.unfiledBookmarksFolderId },
|
||||
{ name: "index", check: v => v === 0 },
|
||||
{ name: "itemType", check: v => v === PlacesUtils.bookmarks.TYPE_BOOKMARK },
|
||||
{ name: "uri", check: v => v instanceof Ci.nsIURI && v.equals(uri) },
|
||||
{ name: "guid", check: v => typeof(v) == "string" && GUID_RE.test(v) },
|
||||
{ name: "parentGuid", check: v => typeof(v) == "string" && GUID_RE.test(v) },
|
||||
{ name: "source", check: v => Object.values(PlacesUtils.bookmarks.SOURCES).includes(v) },
|
||||
] },
|
||||
])]);
|
||||
PlacesUtils.bookmarks.removeItem(id);
|
||||
yield promise;
|
||||
});
|
||||
|
||||
add_task(function* onItemRemoved_separator() {
|
||||
let id = PlacesUtils.bookmarks.getIdForItemAt(PlacesUtils.unfiledBookmarksFolderId, 0);
|
||||
let promise = Promise.all([
|
||||
gBookmarkSkipObserver.setup([
|
||||
"onItemChanged", "onItemRemoved"
|
||||
]),
|
||||
gBookmarksObserver.setup([
|
||||
{ name: "onItemChanged", // This is an unfortunate effect of bug 653910.
|
||||
args: [
|
||||
{ name: "itemId", check: v => typeof(v) == "number" && v > 0 },
|
||||
{ name: "property", check: v => v === "" },
|
||||
{ name: "isAnno", check: v => v === true },
|
||||
{ name: "newValue", check: v => v === "" },
|
||||
{ name: "lastModified", check: v => typeof(v) == "number" && v > 0 },
|
||||
{ name: "itemType", check: v => v === PlacesUtils.bookmarks.TYPE_SEPARATOR },
|
||||
{ name: "parentId", check: v => typeof(v) == "number" && v > 0 },
|
||||
{ name: "guid", check: v => typeof(v) == "string" && GUID_RE.test(v) },
|
||||
{ name: "parentGuid", check: v => typeof(v) == "string" && GUID_RE.test(v) },
|
||||
{ name: "oldValue", check: v => typeof(v) == "string" },
|
||||
{ name: "source", check: v => Object.values(PlacesUtils.bookmarks.SOURCES).includes(v) },
|
||||
] },
|
||||
{ name: "onItemRemoved",
|
||||
args: [
|
||||
{ name: "itemId", check: v => typeof(v) == "number" && v > 0 },
|
||||
{ name: "parentId", check: v => typeof(v) == "number" && v > 0 },
|
||||
{ name: "index", check: v => v === 0 },
|
||||
{ name: "itemType", check: v => v === PlacesUtils.bookmarks.TYPE_SEPARATOR },
|
||||
{ name: "uri", check: v => v === null },
|
||||
{ name: "guid", check: v => typeof(v) == "string" && GUID_RE.test(v) },
|
||||
{ name: "parentGuid", check: v => typeof(v) == "string" && GUID_RE.test(v) },
|
||||
{ name: "source", check: v => Object.values(PlacesUtils.bookmarks.SOURCES).includes(v) },
|
||||
] },
|
||||
])]);
|
||||
PlacesUtils.bookmarks.removeItem(id);
|
||||
yield promise;
|
||||
});
|
||||
|
||||
add_task(function* onItemRemoved_folder() {
|
||||
let id = PlacesUtils.bookmarks.getIdForItemAt(PlacesUtils.unfiledBookmarksFolderId, 0);
|
||||
let promise = Promise.all([
|
||||
gBookmarkSkipObserver.setup([
|
||||
"onItemChanged", "onItemRemoved"
|
||||
]),
|
||||
gBookmarksObserver.setup([
|
||||
{ name: "onItemChanged", // This is an unfortunate effect of bug 653910.
|
||||
args: [
|
||||
{ name: "itemId", check: v => typeof(v) == "number" && v > 0 },
|
||||
{ name: "property", check: v => v === "" },
|
||||
{ name: "isAnno", check: v => v === true },
|
||||
{ name: "newValue", check: v => v === "" },
|
||||
{ name: "lastModified", check: v => typeof(v) == "number" && v > 0 },
|
||||
{ name: "itemType", check: v => v === PlacesUtils.bookmarks.TYPE_FOLDER },
|
||||
{ name: "parentId", check: v => typeof(v) == "number" && v > 0 },
|
||||
{ name: "guid", check: v => typeof(v) == "string" && GUID_RE.test(v) },
|
||||
{ name: "parentGuid", check: v => typeof(v) == "string" && GUID_RE.test(v) },
|
||||
{ name: "oldValue", check: v => typeof(v) == "string" },
|
||||
{ name: "source", check: v => Object.values(PlacesUtils.bookmarks.SOURCES).includes(v) },
|
||||
] },
|
||||
{ name: "onItemRemoved",
|
||||
args: [
|
||||
{ name: "itemId", check: v => typeof(v) == "number" && v > 0 },
|
||||
{ name: "parentId", check: v => typeof(v) == "number" && v > 0 },
|
||||
{ name: "index", check: v => v === 0 },
|
||||
{ name: "itemType", check: v => v === PlacesUtils.bookmarks.TYPE_FOLDER },
|
||||
{ name: "uri", check: v => v === null },
|
||||
{ name: "guid", check: v => typeof(v) == "string" && GUID_RE.test(v) },
|
||||
{ name: "parentGuid", check: v => typeof(v) == "string" && GUID_RE.test(v) },
|
||||
{ name: "source", check: v => Object.values(PlacesUtils.bookmarks.SOURCES).includes(v) },
|
||||
] },
|
||||
])]);
|
||||
PlacesUtils.bookmarks.removeItem(id);
|
||||
yield promise;
|
||||
});
|
||||
|
||||
add_task(function* onItemRemoved_folder_recursive() {
|
||||
const TITLE = "Folder 3";
|
||||
const BMTITLE = "Bookmark 1";
|
||||
let uri = NetUtil.newURI("http://1.mozilla.org/");
|
||||
let promise = Promise.all([
|
||||
gBookmarkSkipObserver.setup([
|
||||
"onItemAdded", "onItemAdded", "onItemAdded", "onItemAdded",
|
||||
"onItemChanged", "onItemRemoved"
|
||||
]),
|
||||
gBookmarksObserver.setup([
|
||||
{ name: "onItemAdded",
|
||||
args: [
|
||||
{ name: "itemId", check: v => typeof(v) == "number" && v > 0 },
|
||||
{ name: "parentId", check: v => v === PlacesUtils.unfiledBookmarksFolderId },
|
||||
{ name: "index", check: v => v === 0 },
|
||||
{ name: "itemType", check: v => v === PlacesUtils.bookmarks.TYPE_FOLDER },
|
||||
{ name: "uri", check: v => v === null },
|
||||
{ name: "title", check: v => v === TITLE },
|
||||
{ name: "dateAdded", check: v => typeof(v) == "number" && v > 0 },
|
||||
{ name: "guid", check: v => typeof(v) == "string" && GUID_RE.test(v) },
|
||||
{ name: "parentGuid", check: v => typeof(v) == "string" && GUID_RE.test(v) },
|
||||
{ name: "source", check: v => Object.values(PlacesUtils.bookmarks.SOURCES).includes(v) },
|
||||
] },
|
||||
{ name: "onItemAdded",
|
||||
args: [
|
||||
{ name: "itemId", check: v => typeof(v) == "number" && v > 0 },
|
||||
{ name: "parentId", check: v => v === PlacesUtils.bookmarks.getIdForItemAt(PlacesUtils.unfiledBookmarksFolderId, 0) },
|
||||
{ name: "index", check: v => v === 0 },
|
||||
{ name: "itemType", check: v => v === PlacesUtils.bookmarks.TYPE_BOOKMARK },
|
||||
{ name: "uri", check: v => v instanceof Ci.nsIURI && v.equals(uri) },
|
||||
{ name: "title", check: v => v === BMTITLE },
|
||||
{ name: "dateAdded", check: v => typeof(v) == "number" && v > 0 },
|
||||
{ name: "guid", check: v => typeof(v) == "string" && GUID_RE.test(v) },
|
||||
{ name: "parentGuid", check: v => typeof(v) == "string" && GUID_RE.test(v) },
|
||||
{ name: "source", check: v => Object.values(PlacesUtils.bookmarks.SOURCES).includes(v) },
|
||||
] },
|
||||
{ name: "onItemAdded",
|
||||
args: [
|
||||
{ name: "itemId", check: v => typeof(v) == "number" && v > 0 },
|
||||
{ name: "parentId", check: v => v === PlacesUtils.bookmarks.getIdForItemAt(PlacesUtils.unfiledBookmarksFolderId, 0) },
|
||||
{ name: "index", check: v => v === 1 },
|
||||
{ name: "itemType", check: v => v === PlacesUtils.bookmarks.TYPE_FOLDER },
|
||||
{ name: "uri", check: v => v === null },
|
||||
{ name: "title", check: v => v === TITLE },
|
||||
{ name: "dateAdded", check: v => typeof(v) == "number" && v > 0 },
|
||||
{ name: "guid", check: v => typeof(v) == "string" && GUID_RE.test(v) },
|
||||
{ name: "parentGuid", check: v => typeof(v) == "string" && GUID_RE.test(v) },
|
||||
{ name: "source", check: v => Object.values(PlacesUtils.bookmarks.SOURCES).includes(v) },
|
||||
] },
|
||||
{ name: "onItemAdded",
|
||||
args: [
|
||||
{ name: "itemId", check: v => typeof(v) == "number" && v > 0 },
|
||||
{ name: "parentId", check: v => v === PlacesUtils.bookmarks.getIdForItemAt(PlacesUtils.bookmarks.getIdForItemAt(PlacesUtils.unfiledBookmarksFolderId, 0), 1) },
|
||||
{ name: "index", check: v => v === 0 },
|
||||
{ name: "itemType", check: v => v === PlacesUtils.bookmarks.TYPE_BOOKMARK },
|
||||
{ name: "uri", check: v => v instanceof Ci.nsIURI && v.equals(uri) },
|
||||
{ name: "title", check: v => v === BMTITLE },
|
||||
{ name: "dateAdded", check: v => typeof(v) == "number" && v > 0 },
|
||||
{ name: "guid", check: v => typeof(v) == "string" && GUID_RE.test(v) },
|
||||
{ name: "parentGuid", check: v => typeof(v) == "string" && GUID_RE.test(v) },
|
||||
{ name: "source", check: v => Object.values(PlacesUtils.bookmarks.SOURCES).includes(v) },
|
||||
] },
|
||||
{ name: "onItemChanged", // This is an unfortunate effect of bug 653910.
|
||||
args: [
|
||||
{ name: "itemId", check: v => typeof(v) == "number" && v > 0 },
|
||||
{ name: "property", check: v => v === "" },
|
||||
{ name: "isAnno", check: v => v === true },
|
||||
{ name: "newValue", check: v => v === "" },
|
||||
{ name: "lastModified", check: v => typeof(v) == "number" && v > 0 },
|
||||
{ name: "itemType", check: v => v === PlacesUtils.bookmarks.TYPE_FOLDER },
|
||||
{ name: "parentId", check: v => typeof(v) == "number" && v > 0 },
|
||||
{ name: "guid", check: v => typeof(v) == "string" && GUID_RE.test(v) },
|
||||
{ name: "parentGuid", check: v => typeof(v) == "string" && GUID_RE.test(v) },
|
||||
{ name: "oldValue", check: v => typeof(v) == "string" },
|
||||
{ name: "source", check: v => Object.values(PlacesUtils.bookmarks.SOURCES).includes(v) },
|
||||
] },
|
||||
{ name: "onItemRemoved",
|
||||
args: [
|
||||
{ name: "itemId", check: v => typeof(v) == "number" && v > 0 },
|
||||
{ name: "parentId", check: v => typeof(v) == "number" && v > 0 },
|
||||
{ name: "index", check: v => v === 0 },
|
||||
{ name: "itemType", check: v => v === PlacesUtils.bookmarks.TYPE_BOOKMARK },
|
||||
{ name: "uri", check: v => v instanceof Ci.nsIURI && v.equals(uri) },
|
||||
{ name: "guid", check: v => typeof(v) == "string" && GUID_RE.test(v) },
|
||||
{ name: "parentGuid", check: v => typeof(v) == "string" && GUID_RE.test(v) },
|
||||
{ name: "source", check: v => Object.values(PlacesUtils.bookmarks.SOURCES).includes(v) },
|
||||
] },
|
||||
{ name: "onItemRemoved",
|
||||
args: [
|
||||
{ name: "itemId", check: v => typeof(v) == "number" && v > 0 },
|
||||
{ name: "parentId", check: v => typeof(v) == "number" && v > 0 },
|
||||
{ name: "index", check: v => v === 1 },
|
||||
{ name: "itemType", check: v => v === PlacesUtils.bookmarks.TYPE_FOLDER },
|
||||
{ name: "uri", check: v => v === null },
|
||||
{ name: "guid", check: v => typeof(v) == "string" && GUID_RE.test(v) },
|
||||
{ name: "parentGuid", check: v => typeof(v) == "string" && GUID_RE.test(v) },
|
||||
{ name: "source", check: v => Object.values(PlacesUtils.bookmarks.SOURCES).includes(v) },
|
||||
] },
|
||||
{ name: "onItemRemoved",
|
||||
args: [
|
||||
{ name: "itemId", check: v => typeof(v) == "number" && v > 0 },
|
||||
{ name: "parentId", check: v => typeof(v) == "number" && v > 0 },
|
||||
{ name: "index", check: v => v === 0 },
|
||||
{ name: "itemType", check: v => v === PlacesUtils.bookmarks.TYPE_BOOKMARK },
|
||||
{ name: "uri", check: v => v instanceof Ci.nsIURI && v.equals(uri) },
|
||||
{ name: "guid", check: v => typeof(v) == "string" && GUID_RE.test(v) },
|
||||
{ name: "parentGuid", check: v => typeof(v) == "string" && GUID_RE.test(v) },
|
||||
{ name: "source", check: v => Object.values(PlacesUtils.bookmarks.SOURCES).includes(v) },
|
||||
] },
|
||||
{ name: "onItemRemoved",
|
||||
args: [
|
||||
{ name: "itemId", check: v => typeof(v) == "number" && v > 0 },
|
||||
{ name: "parentId", check: v => typeof(v) == "number" && v > 0 },
|
||||
{ name: "index", check: v => v === 0 },
|
||||
{ name: "itemType", check: v => v === PlacesUtils.bookmarks.TYPE_FOLDER },
|
||||
{ name: "uri", check: v => v === null },
|
||||
{ name: "guid", check: v => typeof(v) == "string" && GUID_RE.test(v) },
|
||||
{ name: "parentGuid", check: v => typeof(v) == "string" && GUID_RE.test(v) },
|
||||
{ name: "source", check: v => Object.values(PlacesUtils.bookmarks.SOURCES).includes(v) },
|
||||
] },
|
||||
])]);
|
||||
let folder = PlacesUtils.bookmarks.createFolder(PlacesUtils.unfiledBookmarksFolderId,
|
||||
TITLE,
|
||||
PlacesUtils.bookmarks.DEFAULT_INDEX);
|
||||
PlacesUtils.bookmarks.insertBookmark(folder,
|
||||
uri, PlacesUtils.bookmarks.DEFAULT_INDEX,
|
||||
BMTITLE);
|
||||
let folder2 = PlacesUtils.bookmarks.createFolder(folder, TITLE,
|
||||
PlacesUtils.bookmarks.DEFAULT_INDEX);
|
||||
PlacesUtils.bookmarks.insertBookmark(folder2,
|
||||
uri, PlacesUtils.bookmarks.DEFAULT_INDEX,
|
||||
BMTITLE);
|
||||
|
||||
PlacesUtils.bookmarks.removeItem(folder);
|
||||
yield promise;
|
||||
});
|
||||
|
||||
add_task(function cleanup()
|
||||
{
|
||||
PlacesUtils.bookmarks.removeObserver(gBookmarksObserver);
|
||||
PlacesUtils.bookmarks.removeObserver(gBookmarkSkipObserver);
|
||||
});
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
function run_test()
|
||||
{
|
||||
const ROOTS = [
|
||||
PlacesUtils.bookmarksMenuFolderId,
|
||||
PlacesUtils.toolbarFolderId,
|
||||
PlacesUtils.unfiledBookmarksFolderId,
|
||||
PlacesUtils.tagsFolderId,
|
||||
PlacesUtils.placesRootId,
|
||||
PlacesUtils.mobileFolderId,
|
||||
];
|
||||
|
||||
for (let root of ROOTS) {
|
||||
do_check_true(PlacesUtils.isRootItem(root));
|
||||
|
||||
try {
|
||||
PlacesUtils.bookmarks.removeItem(root);
|
||||
do_throw("Trying to remove a root should throw");
|
||||
} catch (ex) {}
|
||||
|
||||
try {
|
||||
PlacesUtils.bookmarks.moveItem(root, PlacesUtils.placesRootId, 0);
|
||||
do_throw("Trying to move a root should throw");
|
||||
} catch (ex) {}
|
||||
|
||||
try {
|
||||
PlacesUtils.bookmarks.removeFolderChildren(root);
|
||||
if (root == PlacesUtils.placesRootId)
|
||||
do_throw("Trying to remove children of the main root should throw");
|
||||
} catch (ex) {
|
||||
if (root != PlacesUtils.placesRootId)
|
||||
do_throw("Trying to remove children of other roots should not throw");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,70 @@
|
|||
/**
|
||||
* This test ensures that reinserting a folder within a transaction gives it
|
||||
* a different GUID, and passes the GUID to the observers.
|
||||
*/
|
||||
|
||||
add_task(function* test_removeFolderTransaction_reinsert() {
|
||||
let folder = yield PlacesUtils.bookmarks.insert({
|
||||
type: PlacesUtils.bookmarks.TYPE_FOLDER,
|
||||
parentGuid: PlacesUtils.bookmarks.menuGuid,
|
||||
title: "Test folder",
|
||||
});
|
||||
let folderId = yield PlacesUtils.promiseItemId(folder.guid);
|
||||
let fx = yield PlacesUtils.bookmarks.insert({
|
||||
parentGuid: folder.guid,
|
||||
title: "Get Firefox!",
|
||||
url: "http://getfirefox.com",
|
||||
});
|
||||
let fxId = yield PlacesUtils.promiseItemId(fx.guid);
|
||||
let tb = yield PlacesUtils.bookmarks.insert({
|
||||
parentGuid: folder.guid,
|
||||
title: "Get Thunderbird!",
|
||||
url: "http://getthunderbird.com",
|
||||
});
|
||||
let tbId = yield PlacesUtils.promiseItemId(tb.guid);
|
||||
|
||||
let notifications = [];
|
||||
function checkNotifications(expected, message) {
|
||||
deepEqual(notifications, expected, message);
|
||||
notifications.length = 0;
|
||||
}
|
||||
|
||||
let observer = {
|
||||
onItemAdded(itemId, parentId, index, type, uri, title, dateAdded, guid,
|
||||
parentGuid) {
|
||||
notifications.push(["onItemAdded", itemId, parentId, guid, parentGuid]);
|
||||
},
|
||||
onItemRemoved(itemId, parentId, index, type, uri, guid, parentGuid) {
|
||||
notifications.push(["onItemRemoved", itemId, parentId, guid, parentGuid]);
|
||||
},
|
||||
};
|
||||
PlacesUtils.bookmarks.addObserver(observer, false);
|
||||
PlacesUtils.registerShutdownFunction(function() {
|
||||
PlacesUtils.bookmarks.removeObserver(observer);
|
||||
});
|
||||
|
||||
let transaction = PlacesUtils.bookmarks.getRemoveFolderTransaction(folderId);
|
||||
deepEqual(notifications, [], "We haven't executed the transaction yet");
|
||||
|
||||
transaction.doTransaction();
|
||||
checkNotifications([
|
||||
["onItemRemoved", tbId, folderId, tb.guid, folder.guid],
|
||||
["onItemRemoved", fxId, folderId, fx.guid, folder.guid],
|
||||
["onItemRemoved", folderId, PlacesUtils.bookmarksMenuFolderId, folder.guid,
|
||||
PlacesUtils.bookmarks.menuGuid],
|
||||
], "Executing transaction should remove folder and its descendants");
|
||||
|
||||
transaction.undoTransaction();
|
||||
// At this point, the restored folder has the same ID, but a different GUID.
|
||||
let newFolderGuid = yield PlacesUtils.promiseItemGuid(folderId);
|
||||
checkNotifications([
|
||||
["onItemAdded", folderId, PlacesUtils.bookmarksMenuFolderId, newFolderGuid,
|
||||
PlacesUtils.bookmarks.menuGuid],
|
||||
], "Undo should reinsert folder with same ID and different GUID");
|
||||
|
||||
transaction.redoTransaction();
|
||||
checkNotifications([
|
||||
["onItemRemoved", folderId, PlacesUtils.bookmarksMenuFolderId,
|
||||
newFolderGuid, PlacesUtils.bookmarks.menuGuid],
|
||||
], "Redo should forward new GUID to observer");
|
||||
});
|
||||
30
toolkit/components/places/tests/bookmarks/test_removeItem.js
Normal file
30
toolkit/components/places/tests/bookmarks/test_removeItem.js
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim:set ts=2 sw=2 sts=2 et: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
var tests = [];
|
||||
|
||||
|
||||
const DEFAULT_INDEX = PlacesUtils.bookmarks.DEFAULT_INDEX;
|
||||
|
||||
function run_test() {
|
||||
// folder to hold this test
|
||||
var folderId =
|
||||
PlacesUtils.bookmarks.createFolder(PlacesUtils.toolbarFolderId,
|
||||
"", DEFAULT_INDEX);
|
||||
|
||||
// add a bookmark to the new folder
|
||||
var bookmarkURI = uri("http://iasdjkf");
|
||||
do_check_false(PlacesUtils.bookmarks.isBookmarked(bookmarkURI));
|
||||
var bookmarkId = PlacesUtils.bookmarks.insertBookmark(folderId, bookmarkURI,
|
||||
DEFAULT_INDEX, "");
|
||||
do_check_eq(PlacesUtils.bookmarks.getItemTitle(bookmarkId), "");
|
||||
|
||||
// remove the folder using removeItem
|
||||
PlacesUtils.bookmarks.removeItem(folderId);
|
||||
do_check_eq(PlacesUtils.bookmarks.getBookmarkIdsForURI(bookmarkURI).length, 0);
|
||||
do_check_false(PlacesUtils.bookmarks.isBookmarked(bookmarkURI));
|
||||
do_check_eq(PlacesUtils.bookmarks.getItemIndex(bookmarkId), -1);
|
||||
}
|
||||
209
toolkit/components/places/tests/bookmarks/test_savedsearches.js
Normal file
209
toolkit/components/places/tests/bookmarks/test_savedsearches.js
Normal file
|
|
@ -0,0 +1,209 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim:set ts=2 sw=2 sts=2 et: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
// get bookmarks root id
|
||||
var root = PlacesUtils.bookmarksMenuFolderId;
|
||||
|
||||
// a search term that matches a default bookmark
|
||||
const searchTerm = "about";
|
||||
|
||||
var testRoot;
|
||||
|
||||
// main
|
||||
function run_test() {
|
||||
// create a folder to hold all the tests
|
||||
// this makes the tests more tolerant of changes to the default bookmarks set
|
||||
// also, name it using the search term, for testing that containers that match don't show up in query results
|
||||
testRoot = PlacesUtils.bookmarks.createFolder(
|
||||
root, searchTerm, PlacesUtils.bookmarks.DEFAULT_INDEX);
|
||||
|
||||
run_next_test();
|
||||
}
|
||||
|
||||
add_test(function test_savedsearches_bookmarks() {
|
||||
// add a bookmark that matches the search term
|
||||
var bookmarkId = PlacesUtils.bookmarks.insertBookmark(
|
||||
root, uri("http://foo.com"), PlacesUtils.bookmarks.DEFAULT_INDEX,
|
||||
searchTerm);
|
||||
|
||||
// create a saved-search that matches a default bookmark
|
||||
var searchId = PlacesUtils.bookmarks.insertBookmark(
|
||||
testRoot, uri("place:terms=" + searchTerm + "&excludeQueries=1&expandQueries=1&queryType=1"),
|
||||
PlacesUtils.bookmarks.DEFAULT_INDEX, searchTerm);
|
||||
|
||||
// query for the test root, expandQueries=0
|
||||
// the query should show up as a regular bookmark
|
||||
try {
|
||||
let options = PlacesUtils.history.getNewQueryOptions();
|
||||
options.expandQueries = 0;
|
||||
let query = PlacesUtils.history.getNewQuery();
|
||||
query.setFolders([testRoot], 1);
|
||||
let result = PlacesUtils.history.executeQuery(query, options);
|
||||
let rootNode = result.root;
|
||||
rootNode.containerOpen = true;
|
||||
let cc = rootNode.childCount;
|
||||
do_check_eq(cc, 1);
|
||||
for (let i = 0; i < cc; i++) {
|
||||
let node = rootNode.getChild(i);
|
||||
// test that queries have valid itemId
|
||||
do_check_true(node.itemId > 0);
|
||||
// test that the container is closed
|
||||
node.QueryInterface(Ci.nsINavHistoryContainerResultNode);
|
||||
do_check_eq(node.containerOpen, false);
|
||||
}
|
||||
rootNode.containerOpen = false;
|
||||
}
|
||||
catch (ex) {
|
||||
do_throw("expandQueries=0 query error: " + ex);
|
||||
}
|
||||
|
||||
// bookmark saved search
|
||||
// query for the test root, expandQueries=1
|
||||
// the query should show up as a query container, with 1 child
|
||||
try {
|
||||
let options = PlacesUtils.history.getNewQueryOptions();
|
||||
options.expandQueries = 1;
|
||||
let query = PlacesUtils.history.getNewQuery();
|
||||
query.setFolders([testRoot], 1);
|
||||
let result = PlacesUtils.history.executeQuery(query, options);
|
||||
let rootNode = result.root;
|
||||
rootNode.containerOpen = true;
|
||||
let cc = rootNode.childCount;
|
||||
do_check_eq(cc, 1);
|
||||
for (let i = 0; i < cc; i++) {
|
||||
let node = rootNode.getChild(i);
|
||||
// test that query node type is container when expandQueries=1
|
||||
do_check_eq(node.type, node.RESULT_TYPE_QUERY);
|
||||
// test that queries (as containers) have valid itemId
|
||||
do_check_true(node.itemId > 0);
|
||||
node.QueryInterface(Ci.nsINavHistoryContainerResultNode);
|
||||
node.containerOpen = true;
|
||||
|
||||
// test that queries have children when excludeItems=1
|
||||
// test that query nodes don't show containers (shouldn't have our folder that matches)
|
||||
// test that queries don't show themselves in query results (shouldn't have our saved search)
|
||||
do_check_eq(node.childCount, 1);
|
||||
|
||||
// test that bookmark shows in query results
|
||||
var item = node.getChild(0);
|
||||
do_check_eq(item.itemId, bookmarkId);
|
||||
|
||||
// XXX - FAILING - test live-update of query results - add a bookmark that matches the query
|
||||
// var tmpBmId = PlacesUtils.bookmarks.insertBookmark(
|
||||
// root, uri("http://" + searchTerm + ".com"),
|
||||
// PlacesUtils.bookmarks.DEFAULT_INDEX, searchTerm + "blah");
|
||||
// do_check_eq(query.childCount, 2);
|
||||
|
||||
// XXX - test live-update of query results - delete a bookmark that matches the query
|
||||
// PlacesUtils.bookmarks.removeItem(tmpBMId);
|
||||
// do_check_eq(query.childCount, 1);
|
||||
|
||||
// test live-update of query results - add a folder that matches the query
|
||||
PlacesUtils.bookmarks.createFolder(
|
||||
root, searchTerm + "zaa", PlacesUtils.bookmarks.DEFAULT_INDEX);
|
||||
do_check_eq(node.childCount, 1);
|
||||
// test live-update of query results - add a query that matches the query
|
||||
PlacesUtils.bookmarks.insertBookmark(
|
||||
root, uri("place:terms=foo&excludeQueries=1&expandQueries=1&queryType=1"),
|
||||
PlacesUtils.bookmarks.DEFAULT_INDEX, searchTerm + "blah");
|
||||
do_check_eq(node.childCount, 1);
|
||||
}
|
||||
rootNode.containerOpen = false;
|
||||
}
|
||||
catch (ex) {
|
||||
do_throw("expandQueries=1 bookmarks query: " + ex);
|
||||
}
|
||||
|
||||
// delete the bookmark search
|
||||
PlacesUtils.bookmarks.removeItem(searchId);
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
add_task(function* test_savedsearches_history() {
|
||||
// add a visit that matches the search term
|
||||
var testURI = uri("http://" + searchTerm + ".com");
|
||||
yield PlacesTestUtils.addVisits({ uri: testURI, title: searchTerm });
|
||||
|
||||
// create a saved-search that matches the visit we added
|
||||
var searchId = PlacesUtils.bookmarks.insertBookmark(testRoot,
|
||||
uri("place:terms=" + searchTerm + "&excludeQueries=1&expandQueries=1&queryType=0"),
|
||||
PlacesUtils.bookmarks.DEFAULT_INDEX, searchTerm);
|
||||
|
||||
// query for the test root, expandQueries=1
|
||||
// the query should show up as a query container, with 1 child
|
||||
try {
|
||||
var options = PlacesUtils.history.getNewQueryOptions();
|
||||
options.expandQueries = 1;
|
||||
var query = PlacesUtils.history.getNewQuery();
|
||||
query.setFolders([testRoot], 1);
|
||||
var result = PlacesUtils.history.executeQuery(query, options);
|
||||
var rootNode = result.root;
|
||||
rootNode.containerOpen = true;
|
||||
var cc = rootNode.childCount;
|
||||
do_check_eq(cc, 1);
|
||||
for (var i = 0; i < cc; i++) {
|
||||
var node = rootNode.getChild(i);
|
||||
// test that query node type is container when expandQueries=1
|
||||
do_check_eq(node.type, node.RESULT_TYPE_QUERY);
|
||||
// test that queries (as containers) have valid itemId
|
||||
do_check_eq(node.itemId, searchId);
|
||||
node.QueryInterface(Ci.nsINavHistoryContainerResultNode);
|
||||
node.containerOpen = true;
|
||||
|
||||
// test that queries have children when excludeItems=1
|
||||
// test that query nodes don't show containers (shouldn't have our folder that matches)
|
||||
// test that queries don't show themselves in query results (shouldn't have our saved search)
|
||||
do_check_eq(node.childCount, 1);
|
||||
|
||||
// test that history visit shows in query results
|
||||
var item = node.getChild(0);
|
||||
do_check_eq(item.type, item.RESULT_TYPE_URI);
|
||||
do_check_eq(item.itemId, -1); // history visit
|
||||
do_check_eq(item.uri, testURI.spec); // history visit
|
||||
|
||||
// test live-update of query results - add a history visit that matches the query
|
||||
yield PlacesTestUtils.addVisits({
|
||||
uri: uri("http://foo.com"),
|
||||
title: searchTerm + "blah"
|
||||
});
|
||||
do_check_eq(node.childCount, 2);
|
||||
|
||||
// test live-update of query results - delete a history visit that matches the query
|
||||
PlacesUtils.history.removePage(uri("http://foo.com"));
|
||||
do_check_eq(node.childCount, 1);
|
||||
node.containerOpen = false;
|
||||
}
|
||||
|
||||
// test live-update of moved queries
|
||||
var tmpFolderId = PlacesUtils.bookmarks.createFolder(
|
||||
testRoot, "foo", PlacesUtils.bookmarks.DEFAULT_INDEX);
|
||||
PlacesUtils.bookmarks.moveItem(
|
||||
searchId, tmpFolderId, PlacesUtils.bookmarks.DEFAULT_INDEX);
|
||||
var tmpFolderNode = rootNode.getChild(0);
|
||||
do_check_eq(tmpFolderNode.itemId, tmpFolderId);
|
||||
tmpFolderNode.QueryInterface(Ci.nsINavHistoryContainerResultNode);
|
||||
tmpFolderNode.containerOpen = true;
|
||||
do_check_eq(tmpFolderNode.childCount, 1);
|
||||
|
||||
// test live-update of renamed queries
|
||||
PlacesUtils.bookmarks.setItemTitle(searchId, "foo");
|
||||
do_check_eq(tmpFolderNode.title, "foo");
|
||||
|
||||
// test live-update of deleted queries
|
||||
PlacesUtils.bookmarks.removeItem(searchId);
|
||||
try {
|
||||
tmpFolderNode = root.getChild(1);
|
||||
do_throw("query was not removed");
|
||||
} catch (ex) {}
|
||||
|
||||
tmpFolderNode.containerOpen = false;
|
||||
rootNode.containerOpen = false;
|
||||
}
|
||||
catch (ex) {
|
||||
do_throw("expandQueries=1 bookmarks query: " + ex);
|
||||
}
|
||||
});
|
||||
50
toolkit/components/places/tests/bookmarks/xpcshell.ini
Normal file
50
toolkit/components/places/tests/bookmarks/xpcshell.ini
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
[DEFAULT]
|
||||
head = head_bookmarks.js
|
||||
tail =
|
||||
skip-if = toolkit == 'android'
|
||||
|
||||
[test_1016953-renaming-uncompressed.js]
|
||||
[test_1017502-bookmarks_foreign_count.js]
|
||||
[test_384228.js]
|
||||
[test_385829.js]
|
||||
[test_388695.js]
|
||||
[test_393498.js]
|
||||
[test_395101.js]
|
||||
[test_395593.js]
|
||||
[test_405938_restore_queries.js]
|
||||
[test_417228-exclude-from-backup.js]
|
||||
[test_417228-other-roots.js]
|
||||
[test_424958-json-quoted-folders.js]
|
||||
[test_448584.js]
|
||||
[test_458683.js]
|
||||
[test_466303-json-remove-backups.js]
|
||||
[test_477583_json-backup-in-future.js]
|
||||
[test_675416.js]
|
||||
[test_711914.js]
|
||||
[test_818584-discard-duplicate-backups.js]
|
||||
[test_818587_compress-bookmarks-backups.js]
|
||||
[test_818593-store-backup-metadata.js]
|
||||
[test_992901-backup-unsorted-hierarchy.js]
|
||||
[test_997030-bookmarks-html-encode.js]
|
||||
[test_1129529.js]
|
||||
[test_async_observers.js]
|
||||
[test_bmindex.js]
|
||||
[test_bookmarkstree_cache.js]
|
||||
[test_bookmarks.js]
|
||||
[test_bookmarks_eraseEverything.js]
|
||||
[test_bookmarks_fetch.js]
|
||||
[test_bookmarks_getRecent.js]
|
||||
[test_bookmarks_insert.js]
|
||||
[test_bookmarks_notifications.js]
|
||||
[test_bookmarks_remove.js]
|
||||
[test_bookmarks_reorder.js]
|
||||
[test_bookmarks_search.js]
|
||||
[test_bookmarks_update.js]
|
||||
[test_changeBookmarkURI.js]
|
||||
[test_getBookmarkedURIFor.js]
|
||||
[test_keywords.js]
|
||||
[test_nsINavBookmarkObserver.js]
|
||||
[test_protectRoots.js]
|
||||
[test_removeFolderTransaction_reinsert.js]
|
||||
[test_removeItem.js]
|
||||
[test_savedsearches.js]
|
||||
Loading…
Add table
Add a link
Reference in a new issue