michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: 'use strict' michael@0: michael@0: const { Cc, Ci } = require('chrome'); michael@0: const bmsrv = Cc['@mozilla.org/browser/nav-bookmarks-service;1']. michael@0: getService(Ci.nsINavBookmarksService); michael@0: const hsrv = Cc['@mozilla.org/browser/nav-history-service;1']. michael@0: getService(Ci.nsINavHistoryService); michael@0: const brsrv = Cc["@mozilla.org/browser/nav-history-service;1"] michael@0: .getService(Ci.nsIBrowserHistory); michael@0: const tagsrv = Cc['@mozilla.org/browser/tagging-service;1']. michael@0: getService(Ci.nsITaggingService); michael@0: const asyncHistory = Cc['@mozilla.org/browser/history;1']. michael@0: getService(Ci.mozIAsyncHistory); michael@0: const { send } = require('sdk/addon/events'); michael@0: const { setTimeout } = require('sdk/timers'); michael@0: const { newURI } = require('sdk/url/utils'); michael@0: const { defer, all } = require('sdk/core/promise'); michael@0: const { once } = require('sdk/system/events'); michael@0: const { set } = require('sdk/preferences/service'); michael@0: const { michael@0: Bookmark, Group, Separator, michael@0: save, search, michael@0: MENU, TOOLBAR, UNSORTED michael@0: } = require('sdk/places/bookmarks'); michael@0: michael@0: function invalidResolve (assert) { michael@0: return function (e) { michael@0: assert.fail('Resolve state should not be called: ' + e); michael@0: }; michael@0: } michael@0: exports.invalidResolve = invalidResolve; michael@0: michael@0: function invalidReject (assert) { michael@0: return function (e) { michael@0: assert.fail('Reject state should not be called: ' + e); michael@0: }; michael@0: } michael@0: exports.invalidReject = invalidReject; michael@0: michael@0: // Removes all children of group michael@0: function clearBookmarks (group) { michael@0: group michael@0: ? bmsrv.removeFolderChildren(group.id) michael@0: : clearAllBookmarks(); michael@0: } michael@0: michael@0: function clearAllBookmarks () { michael@0: [MENU, TOOLBAR, UNSORTED].forEach(clearBookmarks); michael@0: } michael@0: michael@0: function clearHistory (done) { michael@0: hsrv.removeAllPages(); michael@0: once('places-expiration-finished', done); michael@0: } michael@0: michael@0: // Cleans bookmarks and history and disables maintanance michael@0: function resetPlaces (done) { michael@0: // Set last maintenance to current time to prevent michael@0: // Places DB maintenance occuring and locking DB michael@0: set('places.database.lastMaintenance', Math.floor(Date.now() / 1000)); michael@0: clearAllBookmarks(); michael@0: clearHistory(done); michael@0: } michael@0: exports.resetPlaces = resetPlaces; michael@0: michael@0: function compareWithHost (assert, item) { michael@0: let id = item.id; michael@0: let type = item.type === 'group' ? bmsrv.TYPE_FOLDER : bmsrv['TYPE_' + item.type.toUpperCase()]; michael@0: let url = item.url && !item.url.endsWith('/') ? item.url + '/' : item.url; michael@0: michael@0: if (type === bmsrv.TYPE_BOOKMARK) { michael@0: assert.equal(url, bmsrv.getBookmarkURI(id).spec.toString(), 'Matches host url'); michael@0: let tags = tagsrv.getTagsForURI(newURI(item.url)); michael@0: for (let tag of tags) { michael@0: // Handle both array for raw data and set for instances michael@0: if (Array.isArray(item.tags)) michael@0: assert.ok(~item.tags.indexOf(tag), 'has correct tag'); michael@0: else michael@0: assert.ok(item.tags.has(tag), 'has correct tag'); michael@0: } michael@0: assert.equal(tags.length, michael@0: Array.isArray(item.tags) ? item.tags.length : item.tags.size, michael@0: 'matches tag count'); michael@0: } michael@0: if (type !== bmsrv.TYPE_SEPARATOR) { michael@0: assert.equal(item.title, bmsrv.getItemTitle(id), 'Matches host title'); michael@0: } michael@0: assert.equal(item.index, bmsrv.getItemIndex(id), 'Matches host index'); michael@0: assert.equal(item.group.id || item.group, bmsrv.getFolderIdForItem(id), 'Matches host group id'); michael@0: assert.equal(type, bmsrv.getItemType(id), 'Matches host type'); michael@0: } michael@0: exports.compareWithHost = compareWithHost; michael@0: michael@0: function addVisits (urls) { michael@0: var deferred = defer(); michael@0: asyncHistory.updatePlaces([].concat(urls).map(createVisit), { michael@0: handleResult: function () {}, michael@0: handleError: deferred.reject, michael@0: handleCompletion: deferred.resolve michael@0: }); michael@0: michael@0: return deferred.promise; michael@0: } michael@0: exports.addVisits = addVisits; michael@0: michael@0: function removeVisits (urls) { michael@0: [].concat(urls).map(url => { michael@0: hsrv.removePage(newURI(url)); michael@0: }); michael@0: } michael@0: exports.removeVisits = removeVisits; michael@0: michael@0: // Creates a mozIVisitInfo object michael@0: function createVisit (url) { michael@0: let place = {} michael@0: place.uri = newURI(url); michael@0: place.title = "Test visit for " + place.uri.spec; michael@0: place.visits = [{ michael@0: transitionType: hsrv.TRANSITION_LINK, michael@0: visitDate: +(new Date()) * 1000, michael@0: referredURI: undefined michael@0: }]; michael@0: return place; michael@0: } michael@0: michael@0: function createBookmark (data) { michael@0: data = data || {}; michael@0: let item = { michael@0: title: data.title || 'Moz', michael@0: url: data.url || (!data.type || data.type === 'bookmark' ? michael@0: 'http://moz.com/' : michael@0: undefined), michael@0: tags: data.tags || (!data.type || data.type === 'bookmark' ? michael@0: ['firefox'] : michael@0: undefined), michael@0: type: data.type || 'bookmark', michael@0: group: data.group michael@0: }; michael@0: return send('sdk-places-bookmarks-create', item); michael@0: } michael@0: exports.createBookmark = createBookmark; michael@0: michael@0: function createBookmarkItem (data) { michael@0: let deferred = defer(); michael@0: data = data || {}; michael@0: save({ michael@0: title: data.title || 'Moz', michael@0: url: data.url || 'http://moz.com/', michael@0: tags: data.tags || (!data.type || data.type === 'bookmark' ? michael@0: ['firefox'] : michael@0: undefined), michael@0: type: data.type || 'bookmark', michael@0: group: data.group michael@0: }).on('end', function (bookmark) { michael@0: deferred.resolve(bookmark[0]); michael@0: }); michael@0: return deferred.promise; michael@0: } michael@0: exports.createBookmarkItem = createBookmarkItem; michael@0: michael@0: function createBookmarkTree () { michael@0: let agg = []; michael@0: return createBookmarkItem({ type: 'group', title: 'mozgroup' }) michael@0: .then(group => { michael@0: agg.push(group); michael@0: return all([createBookmarkItem({ michael@0: title: 'mozilla.com', michael@0: url: 'http://mozilla.com/', michael@0: group: group, michael@0: tags: ['mozilla', 'firefox', 'thunderbird', 'rust'] michael@0: }), createBookmarkItem({ michael@0: title: 'mozilla.org', michael@0: url: 'http://mozilla.org/', michael@0: group: group, michael@0: tags: ['mozilla', 'firefox', 'thunderbird', 'rust'] michael@0: }), createBookmarkItem({ michael@0: title: 'firefox', michael@0: url: 'http://firefox.com/', michael@0: group: group, michael@0: tags: ['mozilla', 'firefox', 'browser'] michael@0: }), createBookmarkItem({ michael@0: title: 'thunderbird', michael@0: url: 'http://mozilla.org/thunderbird/', michael@0: group: group, michael@0: tags: ['mozilla', 'thunderbird', 'email'] michael@0: }), createBookmarkItem({ michael@0: title: 'moz subfolder', michael@0: group: group, michael@0: type: 'group' michael@0: }) michael@0: ]); michael@0: }) michael@0: .then(results => { michael@0: agg = agg.concat(results); michael@0: let subfolder = results.filter(item => item.type === 'group')[0]; michael@0: return createBookmarkItem({ michael@0: title: 'dark javascript secrets', michael@0: url: 'http://w3schools.com', michael@0: group: subfolder, michael@0: tags: [] michael@0: }); michael@0: }).then(item => { michael@0: agg.push(item); michael@0: return createBookmarkItem( michael@0: { type: 'group', group: MENU, title: 'other stuff' } michael@0: ); michael@0: }).then(newGroup => { michael@0: agg.push(newGroup); michael@0: return all([ michael@0: createBookmarkItem({ michael@0: title: 'mdn', michael@0: url: 'http://developer.mozilla.org/en-US/', michael@0: group: newGroup, michael@0: tags: ['javascript'] michael@0: }), michael@0: createBookmarkItem({ michael@0: title: 'web audio', michael@0: url: 'http://webaud.io', michael@0: group: newGroup, michael@0: tags: ['javascript', 'web audio'] michael@0: }), michael@0: createBookmarkItem({ michael@0: title: 'web audio components', michael@0: url: 'http://component.fm', michael@0: group: newGroup, michael@0: tags: ['javascript', 'web audio', 'components'] michael@0: }) michael@0: ]); michael@0: }).then(results => { michael@0: agg = agg.concat(results); michael@0: return agg; michael@0: }); michael@0: } michael@0: exports.createBookmarkTree = createBookmarkTree;