|
1 /* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
|
2 /* vim:set ts=2 sw=2 sts=2 et: */ |
|
3 /* This Source Code Form is subject to the terms of the Mozilla Public |
|
4 * License, v. 2.0. If a copy of the MPL was not distributed with this |
|
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
6 |
|
7 let bs = PlacesUtils.bookmarks; |
|
8 let hs = PlacesUtils.history; |
|
9 let anno = PlacesUtils.annotations; |
|
10 |
|
11 |
|
12 let bookmarksObserver = { |
|
13 onBeginUpdateBatch: function() { |
|
14 this._beginUpdateBatch = true; |
|
15 }, |
|
16 onEndUpdateBatch: function() { |
|
17 this._endUpdateBatch = true; |
|
18 }, |
|
19 onItemAdded: function(id, folder, index, itemType, uri, title, dateAdded, |
|
20 guid) { |
|
21 this._itemAddedId = id; |
|
22 this._itemAddedParent = folder; |
|
23 this._itemAddedIndex = index; |
|
24 this._itemAddedURI = uri; |
|
25 this._itemAddedTitle = title; |
|
26 |
|
27 // Ensure that we've created a guid for this item. |
|
28 let stmt = DBConn().createStatement( |
|
29 "SELECT guid " |
|
30 + "FROM moz_bookmarks " |
|
31 + "WHERE id = :item_id " |
|
32 ); |
|
33 stmt.params.item_id = id; |
|
34 do_check_true(stmt.executeStep()); |
|
35 do_check_false(stmt.getIsNull(0)); |
|
36 do_check_valid_places_guid(stmt.row.guid); |
|
37 do_check_eq(stmt.row.guid, guid); |
|
38 stmt.finalize(); |
|
39 }, |
|
40 onItemRemoved: function(id, folder, index, itemType) { |
|
41 this._itemRemovedId = id; |
|
42 this._itemRemovedFolder = folder; |
|
43 this._itemRemovedIndex = index; |
|
44 }, |
|
45 onItemChanged: function(id, property, isAnnotationProperty, value, |
|
46 lastModified, itemType) { |
|
47 this._itemChangedId = id; |
|
48 this._itemChangedProperty = property; |
|
49 this._itemChanged_isAnnotationProperty = isAnnotationProperty; |
|
50 this._itemChangedValue = value; |
|
51 }, |
|
52 onItemVisited: function(id, visitID, time) { |
|
53 this._itemVisitedId = id; |
|
54 this._itemVisitedVistId = visitID; |
|
55 this._itemVisitedTime = time; |
|
56 }, |
|
57 onItemMoved: function(id, oldParent, oldIndex, newParent, newIndex, |
|
58 itemType) { |
|
59 this._itemMovedId = id |
|
60 this._itemMovedOldParent = oldParent; |
|
61 this._itemMovedOldIndex = oldIndex; |
|
62 this._itemMovedNewParent = newParent; |
|
63 this._itemMovedNewIndex = newIndex; |
|
64 }, |
|
65 QueryInterface: XPCOMUtils.generateQI([ |
|
66 Ci.nsINavBookmarkObserver, |
|
67 ]) |
|
68 }; |
|
69 |
|
70 |
|
71 // Get bookmarks menu folder id. |
|
72 let root = bs.bookmarksMenuFolder; |
|
73 // Index at which items should begin. |
|
74 let bmStartIndex = 0; |
|
75 |
|
76 |
|
77 function run_test() { |
|
78 run_next_test(); |
|
79 } |
|
80 |
|
81 add_task(function test_bookmarks() { |
|
82 bs.addObserver(bookmarksObserver, false); |
|
83 |
|
84 // test special folders |
|
85 do_check_true(bs.placesRoot > 0); |
|
86 do_check_true(bs.bookmarksMenuFolder > 0); |
|
87 do_check_true(bs.tagsFolder > 0); |
|
88 do_check_true(bs.toolbarFolder > 0); |
|
89 do_check_true(bs.unfiledBookmarksFolder > 0); |
|
90 |
|
91 // test getFolderIdForItem() with bogus item id will throw |
|
92 try { |
|
93 let id = bs.getFolderIdForItem(0); |
|
94 do_throw("getFolderIdForItem accepted bad input"); |
|
95 } catch(ex) {} |
|
96 |
|
97 // test getFolderIdForItem() with bogus item id will throw |
|
98 try { |
|
99 let id = bs.getFolderIdForItem(-1); |
|
100 do_throw("getFolderIdForItem accepted bad input"); |
|
101 } catch(ex) {} |
|
102 |
|
103 // test root parentage |
|
104 do_check_eq(bs.getFolderIdForItem(bs.bookmarksMenuFolder), bs.placesRoot); |
|
105 do_check_eq(bs.getFolderIdForItem(bs.tagsFolder), bs.placesRoot); |
|
106 do_check_eq(bs.getFolderIdForItem(bs.toolbarFolder), bs.placesRoot); |
|
107 do_check_eq(bs.getFolderIdForItem(bs.unfiledBookmarksFolder), bs.placesRoot); |
|
108 |
|
109 // create a folder to hold all the tests |
|
110 // this makes the tests more tolerant of changes to default_places.html |
|
111 let testRoot = bs.createFolder(root, "places bookmarks xpcshell tests", |
|
112 bs.DEFAULT_INDEX); |
|
113 do_check_eq(bookmarksObserver._itemAddedId, testRoot); |
|
114 do_check_eq(bookmarksObserver._itemAddedParent, root); |
|
115 do_check_eq(bookmarksObserver._itemAddedIndex, bmStartIndex); |
|
116 do_check_eq(bookmarksObserver._itemAddedURI, null); |
|
117 let testStartIndex = 0; |
|
118 |
|
119 // test getItemIndex for folders |
|
120 do_check_eq(bs.getItemIndex(testRoot), bmStartIndex); |
|
121 |
|
122 // test getItemType for folders |
|
123 do_check_eq(bs.getItemType(testRoot), bs.TYPE_FOLDER); |
|
124 |
|
125 // insert a bookmark. |
|
126 // the time before we insert, in microseconds |
|
127 let beforeInsert = Date.now() * 1000; |
|
128 do_check_true(beforeInsert > 0); |
|
129 |
|
130 let newId = bs.insertBookmark(testRoot, uri("http://google.com/"), |
|
131 bs.DEFAULT_INDEX, ""); |
|
132 do_check_eq(bookmarksObserver._itemAddedId, newId); |
|
133 do_check_eq(bookmarksObserver._itemAddedParent, testRoot); |
|
134 do_check_eq(bookmarksObserver._itemAddedIndex, testStartIndex); |
|
135 do_check_true(bookmarksObserver._itemAddedURI.equals(uri("http://google.com/"))); |
|
136 do_check_eq(bs.getBookmarkURI(newId).spec, "http://google.com/"); |
|
137 |
|
138 let dateAdded = bs.getItemDateAdded(newId); |
|
139 // dateAdded can equal beforeInsert |
|
140 do_check_true(is_time_ordered(beforeInsert, dateAdded)); |
|
141 |
|
142 // after just inserting, modified should not be set |
|
143 let lastModified = bs.getItemLastModified(newId); |
|
144 do_check_eq(lastModified, dateAdded); |
|
145 |
|
146 // The time before we set the title, in microseconds. |
|
147 let beforeSetTitle = Date.now() * 1000; |
|
148 do_check_true(beforeSetTitle >= beforeInsert); |
|
149 |
|
150 // Workaround possible VM timers issues moving lastModified and dateAdded |
|
151 // to the past. |
|
152 bs.setItemLastModified(newId, --lastModified); |
|
153 bs.setItemDateAdded(newId, --dateAdded); |
|
154 |
|
155 // set bookmark title |
|
156 bs.setItemTitle(newId, "Google"); |
|
157 do_check_eq(bookmarksObserver._itemChangedId, newId); |
|
158 do_check_eq(bookmarksObserver._itemChangedProperty, "title"); |
|
159 do_check_eq(bookmarksObserver._itemChangedValue, "Google"); |
|
160 |
|
161 // check that dateAdded hasn't changed |
|
162 let dateAdded2 = bs.getItemDateAdded(newId); |
|
163 do_check_eq(dateAdded2, dateAdded); |
|
164 |
|
165 // check lastModified after we set the title |
|
166 let lastModified2 = bs.getItemLastModified(newId); |
|
167 LOG("test setItemTitle"); |
|
168 LOG("dateAdded = " + dateAdded); |
|
169 LOG("beforeSetTitle = " + beforeSetTitle); |
|
170 LOG("lastModified = " + lastModified); |
|
171 LOG("lastModified2 = " + lastModified2); |
|
172 do_check_true(is_time_ordered(lastModified, lastModified2)); |
|
173 do_check_true(is_time_ordered(dateAdded, lastModified2)); |
|
174 |
|
175 // get item title |
|
176 let title = bs.getItemTitle(newId); |
|
177 do_check_eq(title, "Google"); |
|
178 |
|
179 // test getItemType for bookmarks |
|
180 do_check_eq(bs.getItemType(newId), bs.TYPE_BOOKMARK); |
|
181 |
|
182 // get item title bad input |
|
183 try { |
|
184 let title = bs.getItemTitle(-3); |
|
185 do_throw("getItemTitle accepted bad input"); |
|
186 } catch(ex) {} |
|
187 |
|
188 // get the folder that the bookmark is in |
|
189 let folderId = bs.getFolderIdForItem(newId); |
|
190 do_check_eq(folderId, testRoot); |
|
191 |
|
192 // test getItemIndex for bookmarks |
|
193 do_check_eq(bs.getItemIndex(newId), testStartIndex); |
|
194 |
|
195 // create a folder at a specific index |
|
196 let workFolder = bs.createFolder(testRoot, "Work", 0); |
|
197 do_check_eq(bookmarksObserver._itemAddedId, workFolder); |
|
198 do_check_eq(bookmarksObserver._itemAddedParent, testRoot); |
|
199 do_check_eq(bookmarksObserver._itemAddedIndex, 0); |
|
200 do_check_eq(bookmarksObserver._itemAddedURI, null); |
|
201 |
|
202 do_check_eq(bs.getItemTitle(workFolder), "Work"); |
|
203 bs.setItemTitle(workFolder, "Work #"); |
|
204 do_check_eq(bs.getItemTitle(workFolder), "Work #"); |
|
205 |
|
206 // add item into subfolder, specifying index |
|
207 let newId2 = bs.insertBookmark(workFolder, |
|
208 uri("http://developer.mozilla.org/"), |
|
209 0, ""); |
|
210 do_check_eq(bookmarksObserver._itemAddedId, newId2); |
|
211 do_check_eq(bookmarksObserver._itemAddedParent, workFolder); |
|
212 do_check_eq(bookmarksObserver._itemAddedIndex, 0); |
|
213 |
|
214 // change item |
|
215 bs.setItemTitle(newId2, "DevMo"); |
|
216 do_check_eq(bookmarksObserver._itemChangedProperty, "title"); |
|
217 |
|
218 // insert item into subfolder |
|
219 let newId3 = bs.insertBookmark(workFolder, |
|
220 uri("http://msdn.microsoft.com/"), |
|
221 bs.DEFAULT_INDEX, ""); |
|
222 do_check_eq(bookmarksObserver._itemAddedId, newId3); |
|
223 do_check_eq(bookmarksObserver._itemAddedParent, workFolder); |
|
224 do_check_eq(bookmarksObserver._itemAddedIndex, 1); |
|
225 |
|
226 // change item |
|
227 bs.setItemTitle(newId3, "MSDN"); |
|
228 do_check_eq(bookmarksObserver._itemChangedProperty, "title"); |
|
229 |
|
230 // remove item |
|
231 bs.removeItem(newId2); |
|
232 do_check_eq(bookmarksObserver._itemRemovedId, newId2); |
|
233 do_check_eq(bookmarksObserver._itemRemovedFolder, workFolder); |
|
234 do_check_eq(bookmarksObserver._itemRemovedIndex, 0); |
|
235 |
|
236 // insert item into subfolder |
|
237 let newId4 = bs.insertBookmark(workFolder, |
|
238 uri("http://developer.mozilla.org/"), |
|
239 bs.DEFAULT_INDEX, ""); |
|
240 do_check_eq(bookmarksObserver._itemAddedId, newId4); |
|
241 do_check_eq(bookmarksObserver._itemAddedParent, workFolder); |
|
242 do_check_eq(bookmarksObserver._itemAddedIndex, 1); |
|
243 |
|
244 // create folder |
|
245 let homeFolder = bs.createFolder(testRoot, "Home", bs.DEFAULT_INDEX); |
|
246 do_check_eq(bookmarksObserver._itemAddedId, homeFolder); |
|
247 do_check_eq(bookmarksObserver._itemAddedParent, testRoot); |
|
248 do_check_eq(bookmarksObserver._itemAddedIndex, 2); |
|
249 |
|
250 // insert item |
|
251 let newId5 = bs.insertBookmark(homeFolder, uri("http://espn.com/"), |
|
252 bs.DEFAULT_INDEX, ""); |
|
253 do_check_eq(bookmarksObserver._itemAddedId, newId5); |
|
254 do_check_eq(bookmarksObserver._itemAddedParent, homeFolder); |
|
255 do_check_eq(bookmarksObserver._itemAddedIndex, 0); |
|
256 |
|
257 // change item |
|
258 bs.setItemTitle(newId5, "ESPN"); |
|
259 do_check_eq(bookmarksObserver._itemChangedId, newId5); |
|
260 do_check_eq(bookmarksObserver._itemChangedProperty, "title"); |
|
261 |
|
262 // insert query item |
|
263 let uri6 = uri("place:domain=google.com&type="+ |
|
264 Ci.nsINavHistoryQueryOptions.RESULTS_AS_SITE_QUERY); |
|
265 let newId6 = bs.insertBookmark(testRoot, uri6, bs.DEFAULT_INDEX, ""); |
|
266 do_check_eq(bookmarksObserver._itemAddedParent, testRoot); |
|
267 do_check_eq(bookmarksObserver._itemAddedIndex, 3); |
|
268 |
|
269 // change item |
|
270 bs.setItemTitle(newId6, "Google Sites"); |
|
271 do_check_eq(bookmarksObserver._itemChangedProperty, "title"); |
|
272 |
|
273 // test getIdForItemAt |
|
274 do_check_eq(bs.getIdForItemAt(testRoot, 0), workFolder); |
|
275 // wrong parent, should return -1 |
|
276 do_check_eq(bs.getIdForItemAt(1337, 0), -1); |
|
277 // wrong index, should return -1 |
|
278 do_check_eq(bs.getIdForItemAt(testRoot, 1337), -1); |
|
279 // wrong parent and index, should return -1 |
|
280 do_check_eq(bs.getIdForItemAt(1337, 1337), -1); |
|
281 |
|
282 // move folder, appending, to different folder |
|
283 let oldParentCC = getChildCount(testRoot); |
|
284 bs.moveItem(workFolder, homeFolder, bs.DEFAULT_INDEX); |
|
285 do_check_eq(bookmarksObserver._itemMovedId, workFolder); |
|
286 do_check_eq(bookmarksObserver._itemMovedOldParent, testRoot); |
|
287 do_check_eq(bookmarksObserver._itemMovedOldIndex, 0); |
|
288 do_check_eq(bookmarksObserver._itemMovedNewParent, homeFolder); |
|
289 do_check_eq(bookmarksObserver._itemMovedNewIndex, 1); |
|
290 |
|
291 // test that the new index is properly stored |
|
292 do_check_eq(bs.getItemIndex(workFolder), 1); |
|
293 do_check_eq(bs.getFolderIdForItem(workFolder), homeFolder); |
|
294 |
|
295 // try to get index of the item from within the old parent folder |
|
296 // check that it has been really removed from there |
|
297 do_check_neq(bs.getIdForItemAt(testRoot, 0), workFolder); |
|
298 // check the last item from within the old parent folder |
|
299 do_check_neq(bs.getIdForItemAt(testRoot, -1), workFolder); |
|
300 // check the index of the item within the new parent folder |
|
301 do_check_eq(bs.getIdForItemAt(homeFolder, 1), workFolder); |
|
302 // try to get index of the last item within the new parent folder |
|
303 do_check_eq(bs.getIdForItemAt(homeFolder, -1), workFolder); |
|
304 // XXX expose FolderCount, and check that the old parent has one less child? |
|
305 do_check_eq(getChildCount(testRoot), oldParentCC-1); |
|
306 |
|
307 // move item, appending, to different folder |
|
308 bs.moveItem(newId5, testRoot, bs.DEFAULT_INDEX); |
|
309 do_check_eq(bookmarksObserver._itemMovedId, newId5); |
|
310 do_check_eq(bookmarksObserver._itemMovedOldParent, homeFolder); |
|
311 do_check_eq(bookmarksObserver._itemMovedOldIndex, 0); |
|
312 do_check_eq(bookmarksObserver._itemMovedNewParent, testRoot); |
|
313 do_check_eq(bookmarksObserver._itemMovedNewIndex, 3); |
|
314 |
|
315 // test get folder's index |
|
316 let tmpFolder = bs.createFolder(testRoot, "tmp", 2); |
|
317 do_check_eq(bs.getItemIndex(tmpFolder), 2); |
|
318 |
|
319 // test setKeywordForBookmark |
|
320 let kwTestItemId = bs.insertBookmark(testRoot, uri("http://keywordtest.com"), |
|
321 bs.DEFAULT_INDEX, ""); |
|
322 try { |
|
323 let dateAdded = bs.getItemDateAdded(kwTestItemId); |
|
324 // after just inserting, modified should not be set |
|
325 let lastModified = bs.getItemLastModified(kwTestItemId); |
|
326 do_check_eq(lastModified, dateAdded); |
|
327 |
|
328 // Workaround possible VM timers issues moving lastModified and dateAdded |
|
329 // to the past. |
|
330 bs.setItemLastModified(kwTestItemId, --lastModified); |
|
331 bs.setItemDateAdded(kwTestItemId, --dateAdded); |
|
332 |
|
333 bs.setKeywordForBookmark(kwTestItemId, "bar"); |
|
334 |
|
335 let lastModified2 = bs.getItemLastModified(kwTestItemId); |
|
336 LOG("test setKeywordForBookmark"); |
|
337 LOG("dateAdded = " + dateAdded); |
|
338 LOG("lastModified = " + lastModified); |
|
339 LOG("lastModified2 = " + lastModified2); |
|
340 do_check_true(is_time_ordered(lastModified, lastModified2)); |
|
341 do_check_true(is_time_ordered(dateAdded, lastModified2)); |
|
342 } catch(ex) { |
|
343 do_throw("setKeywordForBookmark: " + ex); |
|
344 } |
|
345 |
|
346 let lastModified3 = bs.getItemLastModified(kwTestItemId); |
|
347 // test getKeywordForBookmark |
|
348 let k = bs.getKeywordForBookmark(kwTestItemId); |
|
349 do_check_eq("bar", k); |
|
350 |
|
351 // test getKeywordForURI |
|
352 let k = bs.getKeywordForURI(uri("http://keywordtest.com/")); |
|
353 do_check_eq("bar", k); |
|
354 |
|
355 // test getURIForKeyword |
|
356 let u = bs.getURIForKeyword("bar"); |
|
357 do_check_eq("http://keywordtest.com/", u.spec); |
|
358 |
|
359 // test removeFolderChildren |
|
360 // 1) add/remove each child type (bookmark, separator, folder) |
|
361 let tmpFolder = bs.createFolder(testRoot, "removeFolderChildren", |
|
362 bs.DEFAULT_INDEX); |
|
363 bs.insertBookmark(tmpFolder, uri("http://foo9.com/"), bs.DEFAULT_INDEX, ""); |
|
364 bs.createFolder(tmpFolder, "subfolder", bs.DEFAULT_INDEX); |
|
365 bs.insertSeparator(tmpFolder, bs.DEFAULT_INDEX); |
|
366 // 2) confirm that folder has 3 children |
|
367 let options = hs.getNewQueryOptions(); |
|
368 let query = hs.getNewQuery(); |
|
369 query.setFolders([tmpFolder], 1); |
|
370 try { |
|
371 let result = hs.executeQuery(query, options); |
|
372 let rootNode = result.root; |
|
373 rootNode.containerOpen = true; |
|
374 do_check_eq(rootNode.childCount, 3); |
|
375 rootNode.containerOpen = false; |
|
376 } catch(ex) { |
|
377 do_throw("test removeFolderChildren() - querying for children failed: " + ex); |
|
378 } |
|
379 // 3) remove all children |
|
380 bs.removeFolderChildren(tmpFolder); |
|
381 // 4) confirm that folder has 0 children |
|
382 try { |
|
383 result = hs.executeQuery(query, options); |
|
384 let rootNode = result.root; |
|
385 rootNode.containerOpen = true; |
|
386 do_check_eq(rootNode.childCount, 0); |
|
387 rootNode.containerOpen = false; |
|
388 } catch(ex) { |
|
389 do_throw("removeFolderChildren(): " + ex); |
|
390 } |
|
391 |
|
392 // XXX - test folderReadOnly |
|
393 |
|
394 // test bookmark id in query output |
|
395 try { |
|
396 let options = hs.getNewQueryOptions(); |
|
397 let query = hs.getNewQuery(); |
|
398 query.setFolders([testRoot], 1); |
|
399 let result = hs.executeQuery(query, options); |
|
400 let rootNode = result.root; |
|
401 rootNode.containerOpen = true; |
|
402 let cc = rootNode.childCount; |
|
403 LOG("bookmark itemId test: CC = " + cc); |
|
404 do_check_true(cc > 0); |
|
405 for (let i=0; i < cc; ++i) { |
|
406 let node = rootNode.getChild(i); |
|
407 if (node.type == node.RESULT_TYPE_FOLDER || |
|
408 node.type == node.RESULT_TYPE_URI || |
|
409 node.type == node.RESULT_TYPE_SEPARATOR || |
|
410 node.type == node.RESULT_TYPE_QUERY) { |
|
411 do_check_true(node.itemId > 0); |
|
412 } |
|
413 else { |
|
414 do_check_eq(node.itemId, -1); |
|
415 } |
|
416 } |
|
417 rootNode.containerOpen = false; |
|
418 } |
|
419 catch(ex) { |
|
420 do_throw("bookmarks query: " + ex); |
|
421 } |
|
422 |
|
423 // test that multiple bookmarks with same URI show up right in bookmark |
|
424 // folder queries, todo: also to do for complex folder queries |
|
425 try { |
|
426 // test uri |
|
427 let mURI = uri("http://multiple.uris.in.query"); |
|
428 |
|
429 let testFolder = bs.createFolder(testRoot, "test Folder", bs.DEFAULT_INDEX); |
|
430 // add 2 bookmarks |
|
431 bs.insertBookmark(testFolder, mURI, bs.DEFAULT_INDEX, "title 1"); |
|
432 bs.insertBookmark(testFolder, mURI, bs.DEFAULT_INDEX, "title 2"); |
|
433 |
|
434 // query |
|
435 let options = hs.getNewQueryOptions(); |
|
436 let query = hs.getNewQuery(); |
|
437 query.setFolders([testFolder], 1); |
|
438 let result = hs.executeQuery(query, options); |
|
439 let rootNode = result.root; |
|
440 rootNode.containerOpen = true; |
|
441 let cc = rootNode.childCount; |
|
442 do_check_eq(cc, 2); |
|
443 do_check_eq(rootNode.getChild(0).title, "title 1"); |
|
444 do_check_eq(rootNode.getChild(1).title, "title 2"); |
|
445 rootNode.containerOpen = false; |
|
446 } |
|
447 catch(ex) { |
|
448 do_throw("bookmarks query: " + ex); |
|
449 } |
|
450 |
|
451 // test change bookmark uri |
|
452 let newId10 = bs.insertBookmark(testRoot, uri("http://foo10.com/"), |
|
453 bs.DEFAULT_INDEX, ""); |
|
454 let dateAdded = bs.getItemDateAdded(newId10); |
|
455 // after just inserting, modified should not be set |
|
456 let lastModified = bs.getItemLastModified(newId10); |
|
457 do_check_eq(lastModified, dateAdded); |
|
458 |
|
459 // Workaround possible VM timers issues moving lastModified and dateAdded |
|
460 // to the past. |
|
461 bs.setItemLastModified(newId10, --lastModified); |
|
462 bs.setItemDateAdded(newId10, --dateAdded); |
|
463 |
|
464 bs.changeBookmarkURI(newId10, uri("http://foo11.com/")); |
|
465 |
|
466 // check that lastModified is set after we change the bookmark uri |
|
467 let lastModified2 = bs.getItemLastModified(newId10); |
|
468 LOG("test changeBookmarkURI"); |
|
469 LOG("dateAdded = " + dateAdded); |
|
470 LOG("lastModified = " + lastModified); |
|
471 LOG("lastModified2 = " + lastModified2); |
|
472 do_check_true(is_time_ordered(lastModified, lastModified2)); |
|
473 do_check_true(is_time_ordered(dateAdded, lastModified2)); |
|
474 |
|
475 do_check_eq(bookmarksObserver._itemChangedId, newId10); |
|
476 do_check_eq(bookmarksObserver._itemChangedProperty, "uri"); |
|
477 do_check_eq(bookmarksObserver._itemChangedValue, "http://foo11.com/"); |
|
478 |
|
479 // test getBookmarkURI |
|
480 let newId11 = bs.insertBookmark(testRoot, uri("http://foo11.com/"), |
|
481 bs.DEFAULT_INDEX, ""); |
|
482 let bmURI = bs.getBookmarkURI(newId11); |
|
483 do_check_eq("http://foo11.com/", bmURI.spec); |
|
484 |
|
485 // test getBookmarkURI with non-bookmark items |
|
486 try { |
|
487 bs.getBookmarkURI(testRoot); |
|
488 do_throw("getBookmarkURI() should throw for non-bookmark items!"); |
|
489 } catch(ex) {} |
|
490 |
|
491 // test getItemIndex |
|
492 let newId12 = bs.insertBookmark(testRoot, uri("http://foo11.com/"), 1, ""); |
|
493 let bmIndex = bs.getItemIndex(newId12); |
|
494 do_check_eq(1, bmIndex); |
|
495 |
|
496 // insert a bookmark with title ZZZXXXYYY and then search for it. |
|
497 // this test confirms that we can find bookmarks that we haven't visited |
|
498 // (which are "hidden") and that we can find by title. |
|
499 // see bug #369887 for more details |
|
500 let newId13 = bs.insertBookmark(testRoot, uri("http://foobarcheese.com/"), |
|
501 bs.DEFAULT_INDEX, ""); |
|
502 do_check_eq(bookmarksObserver._itemAddedId, newId13); |
|
503 do_check_eq(bookmarksObserver._itemAddedParent, testRoot); |
|
504 do_check_eq(bookmarksObserver._itemAddedIndex, 11); |
|
505 |
|
506 // set bookmark title |
|
507 bs.setItemTitle(newId13, "ZZZXXXYYY"); |
|
508 do_check_eq(bookmarksObserver._itemChangedId, newId13); |
|
509 do_check_eq(bookmarksObserver._itemChangedProperty, "title"); |
|
510 do_check_eq(bookmarksObserver._itemChangedValue, "ZZZXXXYYY"); |
|
511 |
|
512 // check if setting an item annotation triggers onItemChanged |
|
513 bookmarksObserver._itemChangedId = -1; |
|
514 anno.setItemAnnotation(newId3, "test-annotation", "foo", 0, 0); |
|
515 do_check_eq(bookmarksObserver._itemChangedId, newId3); |
|
516 do_check_eq(bookmarksObserver._itemChangedProperty, "test-annotation"); |
|
517 do_check_true(bookmarksObserver._itemChanged_isAnnotationProperty); |
|
518 do_check_eq(bookmarksObserver._itemChangedValue, ""); |
|
519 |
|
520 // test search on bookmark title ZZZXXXYYY |
|
521 try { |
|
522 let options = hs.getNewQueryOptions(); |
|
523 options.excludeQueries = 1; |
|
524 options.queryType = Ci.nsINavHistoryQueryOptions.QUERY_TYPE_BOOKMARKS; |
|
525 let query = hs.getNewQuery(); |
|
526 query.searchTerms = "ZZZXXXYYY"; |
|
527 let result = hs.executeQuery(query, options); |
|
528 let rootNode = result.root; |
|
529 rootNode.containerOpen = true; |
|
530 let cc = rootNode.childCount; |
|
531 do_check_eq(cc, 1); |
|
532 let node = rootNode.getChild(0); |
|
533 do_check_eq(node.title, "ZZZXXXYYY"); |
|
534 do_check_true(node.itemId > 0); |
|
535 rootNode.containerOpen = false; |
|
536 } |
|
537 catch(ex) { |
|
538 do_throw("bookmarks query: " + ex); |
|
539 } |
|
540 |
|
541 // test dateAdded and lastModified properties |
|
542 // for a search query |
|
543 try { |
|
544 let options = hs.getNewQueryOptions(); |
|
545 options.excludeQueries = 1; |
|
546 options.queryType = Ci.nsINavHistoryQueryOptions.QUERY_TYPE_BOOKMARKS; |
|
547 let query = hs.getNewQuery(); |
|
548 query.searchTerms = "ZZZXXXYYY"; |
|
549 let result = hs.executeQuery(query, options); |
|
550 let rootNode = result.root; |
|
551 rootNode.containerOpen = true; |
|
552 let cc = rootNode.childCount; |
|
553 do_check_eq(cc, 1); |
|
554 let node = rootNode.getChild(0); |
|
555 |
|
556 do_check_eq(typeof node.dateAdded, "number"); |
|
557 do_check_true(node.dateAdded > 0); |
|
558 |
|
559 do_check_eq(typeof node.lastModified, "number"); |
|
560 do_check_true(node.lastModified > 0); |
|
561 |
|
562 rootNode.containerOpen = false; |
|
563 } |
|
564 catch(ex) { |
|
565 do_throw("bookmarks query: " + ex); |
|
566 } |
|
567 |
|
568 // test dateAdded and lastModified properties |
|
569 // for a folder query |
|
570 try { |
|
571 let options = hs.getNewQueryOptions(); |
|
572 let query = hs.getNewQuery(); |
|
573 query.setFolders([testRoot], 1); |
|
574 let result = hs.executeQuery(query, options); |
|
575 let rootNode = result.root; |
|
576 rootNode.containerOpen = true; |
|
577 let cc = rootNode.childCount; |
|
578 do_check_true(cc > 0); |
|
579 for (let i = 0; i < cc; i++) { |
|
580 let node = rootNode.getChild(i); |
|
581 |
|
582 if (node.type == node.RESULT_TYPE_URI) { |
|
583 do_check_eq(typeof node.dateAdded, "number"); |
|
584 do_check_true(node.dateAdded > 0); |
|
585 |
|
586 do_check_eq(typeof node.lastModified, "number"); |
|
587 do_check_true(node.lastModified > 0); |
|
588 break; |
|
589 } |
|
590 } |
|
591 rootNode.containerOpen = false; |
|
592 } |
|
593 catch(ex) { |
|
594 do_throw("bookmarks query: " + ex); |
|
595 } |
|
596 |
|
597 // check setItemLastModified() and setItemDateAdded() |
|
598 let newId14 = bs.insertBookmark(testRoot, uri("http://bar.tld/"), |
|
599 bs.DEFAULT_INDEX, ""); |
|
600 let dateAdded = bs.getItemDateAdded(newId14); |
|
601 let lastModified = bs.getItemLastModified(newId14); |
|
602 do_check_eq(lastModified, dateAdded); |
|
603 bs.setItemLastModified(newId14, 1234); |
|
604 let fakeLastModified = bs.getItemLastModified(newId14); |
|
605 do_check_eq(fakeLastModified, 1234); |
|
606 bs.setItemDateAdded(newId14, 4321); |
|
607 let fakeDateAdded = bs.getItemDateAdded(newId14); |
|
608 do_check_eq(fakeDateAdded, 4321); |
|
609 |
|
610 // ensure that removing an item removes its annotations |
|
611 do_check_true(anno.itemHasAnnotation(newId3, "test-annotation")); |
|
612 bs.removeItem(newId3); |
|
613 do_check_false(anno.itemHasAnnotation(newId3, "test-annotation")); |
|
614 |
|
615 // bug 378820 |
|
616 let uri1 = uri("http://foo.tld/a"); |
|
617 bs.insertBookmark(testRoot, uri1, bs.DEFAULT_INDEX, ""); |
|
618 yield promiseAddVisits(uri1); |
|
619 |
|
620 // bug 646993 - test bookmark titles longer than the maximum allowed length |
|
621 let title15 = Array(TITLE_LENGTH_MAX + 5).join("X"); |
|
622 let title15expected = title15.substring(0, TITLE_LENGTH_MAX); |
|
623 let newId15 = bs.insertBookmark(testRoot, uri("http://evil.com/"), |
|
624 bs.DEFAULT_INDEX, title15); |
|
625 |
|
626 do_check_eq(bs.getItemTitle(newId15).length, |
|
627 title15expected.length); |
|
628 do_check_eq(bookmarksObserver._itemAddedTitle, title15expected); |
|
629 // test title length after updates |
|
630 bs.setItemTitle(newId15, title15 + " updated"); |
|
631 do_check_eq(bs.getItemTitle(newId15).length, |
|
632 title15expected.length); |
|
633 do_check_eq(bookmarksObserver._itemChangedId, newId15); |
|
634 do_check_eq(bookmarksObserver._itemChangedProperty, "title"); |
|
635 do_check_eq(bookmarksObserver._itemChangedValue, title15expected); |
|
636 |
|
637 testSimpleFolderResult(); |
|
638 }); |
|
639 |
|
640 function testSimpleFolderResult() { |
|
641 // the time before we create a folder, in microseconds |
|
642 // Workaround possible VM timers issues subtracting 1us. |
|
643 let beforeCreate = Date.now() * 1000 - 1; |
|
644 do_check_true(beforeCreate > 0); |
|
645 |
|
646 // create a folder |
|
647 let parent = bs.createFolder(root, "test", bs.DEFAULT_INDEX); |
|
648 |
|
649 let dateCreated = bs.getItemDateAdded(parent); |
|
650 LOG("check that the folder was created with a valid dateAdded"); |
|
651 LOG("beforeCreate = " + beforeCreate); |
|
652 LOG("dateCreated = " + dateCreated); |
|
653 do_check_true(is_time_ordered(beforeCreate, dateCreated)); |
|
654 |
|
655 // the time before we insert, in microseconds |
|
656 // Workaround possible VM timers issues subtracting 1ms. |
|
657 let beforeInsert = Date.now() * 1000 - 1; |
|
658 do_check_true(beforeInsert > 0); |
|
659 |
|
660 // insert a separator |
|
661 let sep = bs.insertSeparator(parent, bs.DEFAULT_INDEX); |
|
662 |
|
663 let dateAdded = bs.getItemDateAdded(sep); |
|
664 LOG("check that the separator was created with a valid dateAdded"); |
|
665 LOG("beforeInsert = " + beforeInsert); |
|
666 LOG("dateAdded = " + dateAdded); |
|
667 do_check_true(is_time_ordered(beforeInsert, dateAdded)); |
|
668 |
|
669 // re-set item title separately so can test nodes' last modified |
|
670 let item = bs.insertBookmark(parent, uri("about:blank"), |
|
671 bs.DEFAULT_INDEX, ""); |
|
672 bs.setItemTitle(item, "test bookmark"); |
|
673 |
|
674 // see above |
|
675 let folder = bs.createFolder(parent, "test folder", bs.DEFAULT_INDEX); |
|
676 bs.setItemTitle(folder, "test folder"); |
|
677 |
|
678 let longName = Array(TITLE_LENGTH_MAX + 5).join("A"); |
|
679 let folderLongName = bs.createFolder(parent, longName, bs.DEFAULT_INDEX); |
|
680 do_check_eq(bookmarksObserver._itemAddedTitle, longName.substring(0, TITLE_LENGTH_MAX)); |
|
681 |
|
682 let options = hs.getNewQueryOptions(); |
|
683 let query = hs.getNewQuery(); |
|
684 query.setFolders([parent], 1); |
|
685 let result = hs.executeQuery(query, options); |
|
686 let rootNode = result.root; |
|
687 rootNode.containerOpen = true; |
|
688 do_check_eq(rootNode.childCount, 4); |
|
689 |
|
690 let node = rootNode.getChild(0); |
|
691 do_check_true(node.dateAdded > 0); |
|
692 do_check_eq(node.lastModified, node.dateAdded); |
|
693 do_check_eq(node.itemId, sep); |
|
694 do_check_eq(node.title, ""); |
|
695 node = rootNode.getChild(1); |
|
696 do_check_eq(node.itemId, item); |
|
697 do_check_true(node.dateAdded > 0); |
|
698 do_check_true(node.lastModified > 0); |
|
699 do_check_eq(node.title, "test bookmark"); |
|
700 node = rootNode.getChild(2); |
|
701 do_check_eq(node.itemId, folder); |
|
702 do_check_eq(node.title, "test folder"); |
|
703 do_check_true(node.dateAdded > 0); |
|
704 do_check_true(node.lastModified > 0); |
|
705 node = rootNode.getChild(3); |
|
706 do_check_eq(node.itemId, folderLongName); |
|
707 do_check_eq(node.title, longName.substring(0, TITLE_LENGTH_MAX)); |
|
708 do_check_true(node.dateAdded > 0); |
|
709 do_check_true(node.lastModified > 0); |
|
710 |
|
711 // update with another long title |
|
712 bs.setItemTitle(folderLongName, longName + " updated"); |
|
713 do_check_eq(bookmarksObserver._itemChangedId, folderLongName); |
|
714 do_check_eq(bookmarksObserver._itemChangedProperty, "title"); |
|
715 do_check_eq(bookmarksObserver._itemChangedValue, longName.substring(0, TITLE_LENGTH_MAX)); |
|
716 |
|
717 node = rootNode.getChild(3); |
|
718 do_check_eq(node.title, longName.substring(0, TITLE_LENGTH_MAX)); |
|
719 |
|
720 rootNode.containerOpen = false; |
|
721 } |
|
722 |
|
723 function getChildCount(aFolderId) { |
|
724 let cc = -1; |
|
725 try { |
|
726 let options = hs.getNewQueryOptions(); |
|
727 let query = hs.getNewQuery(); |
|
728 query.setFolders([aFolderId], 1); |
|
729 let result = hs.executeQuery(query, options); |
|
730 let rootNode = result.root; |
|
731 rootNode.containerOpen = true; |
|
732 cc = rootNode.childCount; |
|
733 rootNode.containerOpen = false; |
|
734 } catch(ex) { |
|
735 do_throw("getChildCount failed: " + ex); |
|
736 } |
|
737 return cc; |
|
738 } |