~ubuntu-branches/ubuntu/trusty/enigmail/trusty-updates

« back to all changes in this revision

Viewing changes to services/sync/tests/unit/test_bookmark_tracker.js

  • Committer: Package Import Robot
  • Author(s): Chris Coulson
  • Date: 2011-06-07 14:35:53 UTC
  • mfrom: (0.12.1 upstream)
  • Revision ID: package-import@ubuntu.com-20110607143553-fbgqhhvh8g8h6j1y
Tags: 2:1.2~a2~cvs20110606t2200-0ubuntu1
* Update to latest trunk snapshot for Thunderbird beta compat

* Remove build/pgo/profileserver.py from debian/clean. The new build
  system has a target depending on this
  - update debian/clean
* Drop debian/patches/autoconf.diff, just generate this at build time
* Refresh debian/patches/build_system_dont_link_libxul.diff
* libipc seems to be renamed to libipc-pipe. Fix genxpi and chrome.manifest
  to fix this 
  - add debian/patches/ipc-pipe_rename.diff
  - update debian/patches/series
* The makefiles in extensions/enigmail/ipc have an incorrect DEPTH
  attribute. Fix this so that they can find the rest of the build system
  - add debian/patches/makefile_depth.diff
  - update debian/patches/series
* Drop debian/patches/makefile-in-empty-xpcom-fix.diff - fixed in the
  current version
* Don't register a class ID multiple times, as this breaks enigmail entirely
  - add debian/patches/dont_register_cids_multiple_times.diff
  - update debian/patches/series
* Look for the Thunderbird 5 SDK
  - update debian/rules
  - update debian/control
* Run autoconf2.13 at build time
  - update debian/rules
  - update debian/control
* Add useless mesa-common-dev build-dep, just to satisfy the build system.
  We should just patch this out entirely really, but that's for another upload
  - update debian/control

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
Cu.import("resource://services-sync/engines/bookmarks.js");
 
2
Cu.import("resource://services-sync/engines.js");
 
3
Cu.import("resource://services-sync/util.js");
 
4
Cu.import("resource://gre/modules/PlacesUtils.jsm");
 
5
 
 
6
Engines.register(BookmarksEngine);
 
7
let engine = Engines.get("bookmarks");
 
8
let store  = engine._store;
 
9
store.wipe();
 
10
 
 
11
function test_copying_places() {
 
12
 
 
13
  // Gecko <2.0
 
14
  if (store._haveGUIDColumn) {
 
15
    _("We have a GUID column; not testing anno GUID fixing.");
 
16
    return;
 
17
  }
 
18
 
 
19
  //
 
20
  // Copied and simplified from PlacesUIUtils, to which we don't have easy
 
21
  // access.
 
22
  //
 
23
  let ptm;
 
24
 
 
25
  try {
 
26
    ptm = Components.classes["@mozilla.org/browser/placesTransactionsService;1"]
 
27
                      .getService(Ci.nsIPlacesTransactionsService);
 
28
  } catch (ex) {
 
29
    _("Can't test transactions -- not running with a browser context.");
 
30
    return;
 
31
  }
 
32
 
 
33
  function getBookmarkItemCopyTransaction(aData, aContainer, aIndex,
 
34
                                          aExcludeAnnotations) {
 
35
    var itemURL = PlacesUtils._uri(aData.uri);
 
36
    var itemTitle = aData.title;
 
37
    var keyword = aData.keyword || null;
 
38
    var annos = aData.annos || [];
 
39
    // always exclude GUID when copying any item
 
40
    var excludeAnnos = [PlacesUtils.GUID_ANNO];
 
41
    if (aExcludeAnnotations)
 
42
      excludeAnnos = excludeAnnos.concat(aExcludeAnnotations);
 
43
    annos = annos.filter(function(aValue, aIndex, aArray) {
 
44
      return excludeAnnos.indexOf(aValue.name) == -1;
 
45
    });
 
46
    var childTxns = [];
 
47
    if (aData.dateAdded)
 
48
      childTxns.push(ptm.editItemDateAdded(null, aData.dateAdded));
 
49
    if (aData.lastModified)
 
50
      childTxns.push(ptm.editItemLastModified(null, aData.lastModified));
 
51
    if (aData.tags) {
 
52
      var tags = aData.tags.split(", ");
 
53
      var storedTags = PlacesUtils.tagging.getTagsForURI(itemURL, {});
 
54
      tags = tags.filter(function (aTag) {
 
55
        return (storedTags.indexOf(aTag) == -1);
 
56
      }, this);
 
57
      if (tags.length)
 
58
        childTxns.push(ptm.tagURI(itemURL, tags));
 
59
    }
 
60
 
 
61
    return ptm.createItem(itemURL, aContainer, aIndex, itemTitle, keyword,
 
62
                          annos, childTxns);
 
63
  }
 
64
 
 
65
  function getFolderCopyTransaction(aData, aContainer, aIndex) {
 
66
    function getChildItemsTransactions(aChildren) {
 
67
      var childItemsTransactions = [];
 
68
      var cc = aChildren.length;
 
69
      var index = aIndex;
 
70
      for (var i = 0; i < cc; ++i) {
 
71
        var txn = null;
 
72
        var node = aChildren[i];
 
73
 
 
74
        // Make sure that items are given the correct index, this will be
 
75
        // passed by the transaction manager to the backend for the insertion.
 
76
        // Insertion behaves differently if index == DEFAULT_INDEX (append)
 
77
        if (aIndex != PlacesUtils.bookmarks.DEFAULT_INDEX)
 
78
          index = i;
 
79
 
 
80
        if (node.type == PlacesUtils.TYPE_X_MOZ_PLACE_CONTAINER)
 
81
          txn = getFolderCopyTransaction(node, aContainer, index);
 
82
        else // (node.type == PlacesUtils.TYPE_X_MOZ_PLACE)
 
83
          txn = getBookmarkItemCopyTransaction(node, -1, index);
 
84
 
 
85
        if (txn)
 
86
          childItemsTransactions.push(txn);
 
87
      }
 
88
      return childItemsTransactions;
 
89
    }
 
90
 
 
91
    // tag folders use tag transactions
 
92
    if (aContainer == PlacesUtils.tagsFolderId) {
 
93
      var txns = [];
 
94
      if (aData.children) {
 
95
        aData.children.forEach(function(aChild) {
 
96
          txns.push(ptm.tagURI(PlacesUtils._uri(aChild.uri), [aData.title]));
 
97
        }, this);
 
98
      }
 
99
      return ptm.aggregateTransactions("addTags", txns);
 
100
    }
 
101
    else {
 
102
      var childItems = getChildItemsTransactions(aData.children);
 
103
      if (aData.dateAdded)
 
104
        childItems.push(ptm.editItemDateAdded(null, aData.dateAdded));
 
105
      if (aData.lastModified)
 
106
        childItems.push(ptm.editItemLastModified(null, aData.lastModified));
 
107
 
 
108
      var annos = aData.annos || [];
 
109
      annos = annos.filter(function(aAnno) {
 
110
        // always exclude GUID when copying any item
 
111
        return aAnno.name != PlacesUtils.GUID_ANNO;
 
112
      });
 
113
      return ptm.createFolder(aData.title, aContainer, aIndex, annos, childItems);
 
114
    }
 
115
  }
 
116
 
 
117
  //
 
118
  // End simplified PlacesUIUtils code.
 
119
  //
 
120
 
 
121
  let tracker = engine._tracker;
 
122
  tracker.clearChangedIDs();
 
123
 
 
124
  try {
 
125
    _("Test copying using Places transactions.");
 
126
    Svc.Obs.notify("weave:engine:start-tracking");
 
127
 
 
128
    _("Set up source and destination folders.");
 
129
    let f1 = Svc.Bookmark.createFolder(PlacesUtils.toolbarFolderId, "Folder One",
 
130
                                       Svc.Bookmark.DEFAULT_INDEX);
 
131
    let f2 = Svc.Bookmark.createFolder(PlacesUtils.toolbarFolderId, "Folder Two",
 
132
                                       Svc.Bookmark.DEFAULT_INDEX);
 
133
 
 
134
    let b1 = Svc.Bookmark.insertBookmark(f1,
 
135
                                         Utils.makeURI("http://example.com/"),
 
136
                                         Svc.Bookmark.DEFAULT_INDEX,
 
137
                                         "Example!");
 
138
 
 
139
    _("F1: " + f1 + "; F2: " + f2 + "; B1: " + b1);
 
140
 
 
141
    _("Fetch GUIDs so our anno exists.");
 
142
    let f1GUID = store.GUIDForId(f1);
 
143
    let f2GUID = store.GUIDForId(f2);
 
144
    let b1GUID = store.GUIDForId(b1);
 
145
    do_check_true(!!f1GUID);
 
146
    do_check_true(!!f2GUID);
 
147
    do_check_true(!!b1GUID);
 
148
 
 
149
    _("Make sure the destination folder is empty.");
 
150
    do_check_eq(PlacesUtils.getFolderContents(f2, false, true).root.childCount, 0);
 
151
 
 
152
    let f1Node = PlacesUtils.getFolderContents(f1, false, false);
 
153
    _("Node to copy: " + f1Node.root.itemId);
 
154
 
 
155
    let serialized = PlacesUtils.wrapNode(f1Node.root, PlacesUtils.TYPE_X_MOZ_PLACE_CONTAINER);
 
156
    _("Serialized to " + serialized);
 
157
 
 
158
    let raw = PlacesUtils.unwrapNodes(serialized, PlacesUtils.TYPE_X_MOZ_PLACE_CONTAINER).shift();
 
159
    let transaction = getFolderCopyTransaction(raw, f2, Svc.Bookmark.DEFAULT_INDEX, true);
 
160
 
 
161
    _("Run the copy transaction.");
 
162
    ptm.doTransaction(transaction);
 
163
 
 
164
    _("Verify that items have been copied.");
 
165
    let f2Node = PlacesUtils.getFolderContents(f2, false, true);
 
166
    do_check_eq(f2Node.root.childCount, 1);
 
167
 
 
168
    _("Verify that the copied folder has different GUIDs.");
 
169
    let c0 = f2Node.root.getChild(0);
 
170
    do_check_eq(c0.title, "Folder One");
 
171
    do_check_neq(c0.itemId, f1);
 
172
    do_check_neq(store.GUIDForId(c0.itemId), f1GUID);
 
173
 
 
174
    _("Verify that this copied folder contains a copied bookmark with different GUIDs.");
 
175
    c0 = c0.QueryInterface(Ci.nsINavHistoryContainerResultNode);
 
176
    c0.containerOpen = true;
 
177
 
 
178
    do_check_eq(c0.childCount, 1);
 
179
    let b0 = c0.getChild(0);
 
180
 
 
181
    do_check_eq(b0.title, "Example!");
 
182
    do_check_eq(b0.uri, "http://example.com/");
 
183
    do_check_neq(b0.itemId, b1);
 
184
    do_check_neq(store.GUIDForId(b0.itemId), b1GUID);
 
185
 
 
186
  } finally {
 
187
    tracker.clearChangedIDs();
 
188
    Svc.Obs.notify("weave:engine:stop-tracking");
 
189
  }
 
190
}
 
191
 
 
192
function test_tracking() {
 
193
  _("Verify we've got an empty tracker to work with.");
 
194
  let tracker = engine._tracker;
 
195
  do_check_eq([id for (id in tracker.changedIDs)].length, 0);
 
196
 
 
197
  let folder = Svc.Bookmark.createFolder(Svc.Bookmark.bookmarksMenuFolder,
 
198
                                         "Test Folder",
 
199
                                         Svc.Bookmark.DEFAULT_INDEX);
 
200
  function createBmk() {
 
201
    return Svc.Bookmark.insertBookmark(folder,
 
202
                                       Utils.makeURI("http://getfirefox.com"),
 
203
                                       Svc.Bookmark.DEFAULT_INDEX,
 
204
                                       "Get Firefox!");
 
205
  }
 
206
 
 
207
  try {
 
208
    _("Create bookmark. Won't show because we haven't started tracking yet");
 
209
    createBmk();
 
210
    do_check_eq([id for (id in tracker.changedIDs)].length, 0);
 
211
 
 
212
    _("Tell the tracker to start tracking changes.");
 
213
    Svc.Obs.notify("weave:engine:start-tracking");
 
214
    createBmk();
 
215
    // We expect two changed items because the containing folder
 
216
    // changed as well (new child).
 
217
    do_check_eq([id for (id in tracker.changedIDs)].length, 2);
 
218
 
 
219
    _("Notifying twice won't do any harm.");
 
220
    Svc.Obs.notify("weave:engine:start-tracking");
 
221
    createBmk();
 
222
    do_check_eq([id for (id in tracker.changedIDs)].length, 3);
 
223
 
 
224
    _("Let's stop tracking again.");
 
225
    tracker.clearChangedIDs();
 
226
    Svc.Obs.notify("weave:engine:stop-tracking");
 
227
    createBmk();
 
228
    do_check_eq([id for (id in tracker.changedIDs)].length, 0);
 
229
 
 
230
    _("Notifying twice won't do any harm.");
 
231
    Svc.Obs.notify("weave:engine:stop-tracking");
 
232
    createBmk();
 
233
    do_check_eq([id for (id in tracker.changedIDs)].length, 0);
 
234
 
 
235
  } finally {
 
236
    _("Clean up.");
 
237
    store.wipe();
 
238
    tracker.clearChangedIDs();
 
239
    Svc.Obs.notify("weave:engine:stop-tracking");
 
240
  }
 
241
}
 
242
 
 
243
function test_onItemChanged() {
 
244
  // Anno that's in ANNOS_TO_TRACK.
 
245
  const GENERATOR_ANNO = "microsummary/generatorURI";
 
246
 
 
247
  _("Verify we've got an empty tracker to work with.");
 
248
  let tracker = engine._tracker;
 
249
  do_check_eq([id for (id in tracker.changedIDs)].length, 0);
 
250
 
 
251
  try {
 
252
    Svc.Obs.notify("weave:engine:stop-tracking");
 
253
    let folder = Svc.Bookmark.createFolder(Svc.Bookmark.bookmarksMenuFolder,
 
254
                                           "Parent",
 
255
                                           Svc.Bookmark.DEFAULT_INDEX);
 
256
    _("Track changes to annos.");
 
257
    let b = Svc.Bookmark.insertBookmark(folder,
 
258
                                        Utils.makeURI("http://getfirefox.com"),
 
259
                                        Svc.Bookmark.DEFAULT_INDEX,
 
260
                                        "Get Firefox!");
 
261
    let bGUID = engine._store.GUIDForId(b);
 
262
    _("New item is " + b);
 
263
    _("GUID: " + bGUID);
 
264
 
 
265
    Svc.Obs.notify("weave:engine:start-tracking");
 
266
    Svc.Annos.setItemAnnotation(b, GENERATOR_ANNO, "http://foo.bar/", 0,
 
267
                                Svc.Annos.EXPIRE_NEVER);
 
268
    do_check_true(tracker.changedIDs[bGUID] > 0);
 
269
 
 
270
  } finally {
 
271
    _("Clean up.");
 
272
    store.wipe();
 
273
    tracker.clearChangedIDs();
 
274
    Svc.Obs.notify("weave:engine:stop-tracking");
 
275
  }
 
276
}
 
277
 
 
278
function run_test() {
 
279
  initTestLogging("Trace");
 
280
 
 
281
  Log4Moz.repository.getLogger("Engine.Bookmarks").level = Log4Moz.Level.Trace;
 
282
  Log4Moz.repository.getLogger("Store.Bookmarks").level = Log4Moz.Level.Trace;
 
283
  Log4Moz.repository.getLogger("Tracker.Bookmarks").level = Log4Moz.Level.Trace;
 
284
 
 
285
  test_onItemChanged();
 
286
  test_copying_places();
 
287
  test_tracking();
 
288
}
 
289