|
1 /* Any copyright is dedicated to the Public Domain. |
|
2 http://creativecommons.org/publicdomain/zero/1.0/ */ |
|
3 |
|
4 Cu.import("resource://gre/modules/PlacesUtils.jsm"); |
|
5 Cu.import("resource://services-sync/engines.js"); |
|
6 Cu.import("resource://services-sync/engines/bookmarks.js"); |
|
7 Cu.import("resource://services-sync/service.js"); |
|
8 Cu.import("resource://services-sync/util.js"); |
|
9 |
|
10 const PARENT_ANNO = "sync/parent"; |
|
11 |
|
12 Service.engineManager.register(BookmarksEngine); |
|
13 |
|
14 let engine = Service.engineManager.get("bookmarks"); |
|
15 let store = engine._store; |
|
16 let tracker = engine._tracker; |
|
17 |
|
18 // Don't write some persistence files asynchronously. |
|
19 tracker.persistChangedIDs = false; |
|
20 |
|
21 let fxuri = Utils.makeURI("http://getfirefox.com/"); |
|
22 let tburi = Utils.makeURI("http://getthunderbird.com/"); |
|
23 |
|
24 add_test(function test_ignore_specials() { |
|
25 _("Ensure that we can't delete bookmark roots."); |
|
26 |
|
27 // Belt... |
|
28 let record = new BookmarkFolder("bookmarks", "toolbar", "folder"); |
|
29 record.deleted = true; |
|
30 do_check_neq(null, store.idForGUID("toolbar")); |
|
31 |
|
32 store.applyIncoming(record); |
|
33 |
|
34 // Ensure that the toolbar exists. |
|
35 do_check_neq(null, store.idForGUID("toolbar")); |
|
36 |
|
37 // This will fail painfully in getItemType if the deletion worked. |
|
38 engine._buildGUIDMap(); |
|
39 |
|
40 // Braces... |
|
41 store.remove(record); |
|
42 do_check_neq(null, store.idForGUID("toolbar")); |
|
43 engine._buildGUIDMap(); |
|
44 |
|
45 store.wipe(); |
|
46 run_next_test(); |
|
47 }); |
|
48 |
|
49 add_test(function test_bookmark_create() { |
|
50 try { |
|
51 _("Ensure the record isn't present yet."); |
|
52 let ids = PlacesUtils.bookmarks.getBookmarkIdsForURI(fxuri, {}); |
|
53 do_check_eq(ids.length, 0); |
|
54 |
|
55 _("Let's create a new record."); |
|
56 let fxrecord = new Bookmark("bookmarks", "get-firefox1"); |
|
57 fxrecord.bmkUri = fxuri.spec; |
|
58 fxrecord.description = "Firefox is awesome."; |
|
59 fxrecord.title = "Get Firefox!"; |
|
60 fxrecord.tags = ["firefox", "awesome", "browser"]; |
|
61 fxrecord.keyword = "awesome"; |
|
62 fxrecord.loadInSidebar = false; |
|
63 fxrecord.parentName = "Bookmarks Toolbar"; |
|
64 fxrecord.parentid = "toolbar"; |
|
65 store.applyIncoming(fxrecord); |
|
66 |
|
67 _("Verify it has been created correctly."); |
|
68 let id = store.idForGUID(fxrecord.id); |
|
69 do_check_eq(store.GUIDForId(id), fxrecord.id); |
|
70 do_check_eq(PlacesUtils.bookmarks.getItemType(id), |
|
71 PlacesUtils.bookmarks.TYPE_BOOKMARK); |
|
72 do_check_true(PlacesUtils.bookmarks.getBookmarkURI(id).equals(fxuri)); |
|
73 do_check_eq(PlacesUtils.bookmarks.getItemTitle(id), fxrecord.title); |
|
74 do_check_eq(PlacesUtils.annotations.getItemAnnotation(id, "bookmarkProperties/description"), |
|
75 fxrecord.description); |
|
76 do_check_eq(PlacesUtils.bookmarks.getFolderIdForItem(id), |
|
77 PlacesUtils.bookmarks.toolbarFolder); |
|
78 do_check_eq(PlacesUtils.bookmarks.getKeywordForBookmark(id), fxrecord.keyword); |
|
79 |
|
80 _("Have the store create a new record object. Verify that it has the same data."); |
|
81 let newrecord = store.createRecord(fxrecord.id); |
|
82 do_check_true(newrecord instanceof Bookmark); |
|
83 for each (let property in ["type", "bmkUri", "description", "title", |
|
84 "keyword", "parentName", "parentid"]) { |
|
85 do_check_eq(newrecord[property], fxrecord[property]); |
|
86 } |
|
87 do_check_true(Utils.deepEquals(newrecord.tags.sort(), |
|
88 fxrecord.tags.sort())); |
|
89 |
|
90 _("The calculated sort index is based on frecency data."); |
|
91 do_check_true(newrecord.sortindex >= 150); |
|
92 |
|
93 _("Create a record with some values missing."); |
|
94 let tbrecord = new Bookmark("bookmarks", "thunderbird1"); |
|
95 tbrecord.bmkUri = tburi.spec; |
|
96 tbrecord.parentName = "Bookmarks Toolbar"; |
|
97 tbrecord.parentid = "toolbar"; |
|
98 store.applyIncoming(tbrecord); |
|
99 |
|
100 _("Verify it has been created correctly."); |
|
101 id = store.idForGUID(tbrecord.id); |
|
102 do_check_eq(store.GUIDForId(id), tbrecord.id); |
|
103 do_check_eq(PlacesUtils.bookmarks.getItemType(id), |
|
104 PlacesUtils.bookmarks.TYPE_BOOKMARK); |
|
105 do_check_true(PlacesUtils.bookmarks.getBookmarkURI(id).equals(tburi)); |
|
106 do_check_eq(PlacesUtils.bookmarks.getItemTitle(id), null); |
|
107 let error; |
|
108 try { |
|
109 PlacesUtils.annotations.getItemAnnotation(id, "bookmarkProperties/description"); |
|
110 } catch(ex) { |
|
111 error = ex; |
|
112 } |
|
113 do_check_eq(error.result, Cr.NS_ERROR_NOT_AVAILABLE); |
|
114 do_check_eq(PlacesUtils.bookmarks.getFolderIdForItem(id), |
|
115 PlacesUtils.bookmarks.toolbarFolder); |
|
116 do_check_eq(PlacesUtils.bookmarks.getKeywordForBookmark(id), null); |
|
117 } finally { |
|
118 _("Clean up."); |
|
119 store.wipe(); |
|
120 run_next_test(); |
|
121 } |
|
122 }); |
|
123 |
|
124 add_test(function test_bookmark_update() { |
|
125 try { |
|
126 _("Create a bookmark whose values we'll change."); |
|
127 let bmk1_id = PlacesUtils.bookmarks.insertBookmark( |
|
128 PlacesUtils.bookmarks.toolbarFolder, fxuri, |
|
129 PlacesUtils.bookmarks.DEFAULT_INDEX, |
|
130 "Get Firefox!"); |
|
131 PlacesUtils.annotations.setItemAnnotation( |
|
132 bmk1_id, "bookmarkProperties/description", "Firefox is awesome.", 0, |
|
133 PlacesUtils.annotations.EXPIRE_NEVER); |
|
134 PlacesUtils.bookmarks.setKeywordForBookmark(bmk1_id, "firefox"); |
|
135 let bmk1_guid = store.GUIDForId(bmk1_id); |
|
136 |
|
137 _("Update the record with some null values."); |
|
138 let record = store.createRecord(bmk1_guid); |
|
139 record.title = null; |
|
140 record.description = null; |
|
141 record.keyword = null; |
|
142 record.tags = null; |
|
143 store.applyIncoming(record); |
|
144 |
|
145 _("Verify that the values have been cleared."); |
|
146 do_check_throws(function () { |
|
147 PlacesUtils.annotations.getItemAnnotation( |
|
148 bmk1_id, "bookmarkProperties/description"); |
|
149 }, Cr.NS_ERROR_NOT_AVAILABLE); |
|
150 do_check_eq(PlacesUtils.bookmarks.getItemTitle(bmk1_id), null); |
|
151 do_check_eq(PlacesUtils.bookmarks.getKeywordForBookmark(bmk1_id), null); |
|
152 } finally { |
|
153 _("Clean up."); |
|
154 store.wipe(); |
|
155 run_next_test(); |
|
156 } |
|
157 }); |
|
158 |
|
159 add_test(function test_bookmark_createRecord() { |
|
160 try { |
|
161 _("Create a bookmark without a description or title."); |
|
162 let bmk1_id = PlacesUtils.bookmarks.insertBookmark( |
|
163 PlacesUtils.bookmarks.toolbarFolder, fxuri, |
|
164 PlacesUtils.bookmarks.DEFAULT_INDEX, null); |
|
165 let bmk1_guid = store.GUIDForId(bmk1_id); |
|
166 |
|
167 _("Verify that the record is created accordingly."); |
|
168 let record = store.createRecord(bmk1_guid); |
|
169 do_check_eq(record.title, null); |
|
170 do_check_eq(record.description, null); |
|
171 do_check_eq(record.keyword, null); |
|
172 |
|
173 } finally { |
|
174 _("Clean up."); |
|
175 store.wipe(); |
|
176 run_next_test(); |
|
177 } |
|
178 }); |
|
179 |
|
180 add_test(function test_folder_create() { |
|
181 try { |
|
182 _("Create a folder."); |
|
183 let folder = new BookmarkFolder("bookmarks", "testfolder-1"); |
|
184 folder.parentName = "Bookmarks Toolbar"; |
|
185 folder.parentid = "toolbar"; |
|
186 folder.title = "Test Folder"; |
|
187 store.applyIncoming(folder); |
|
188 |
|
189 _("Verify it has been created correctly."); |
|
190 let id = store.idForGUID(folder.id); |
|
191 do_check_eq(PlacesUtils.bookmarks.getItemType(id), |
|
192 PlacesUtils.bookmarks.TYPE_FOLDER); |
|
193 do_check_eq(PlacesUtils.bookmarks.getItemTitle(id), folder.title); |
|
194 do_check_eq(PlacesUtils.bookmarks.getFolderIdForItem(id), |
|
195 PlacesUtils.bookmarks.toolbarFolder); |
|
196 |
|
197 _("Have the store create a new record object. Verify that it has the same data."); |
|
198 let newrecord = store.createRecord(folder.id); |
|
199 do_check_true(newrecord instanceof BookmarkFolder); |
|
200 for each (let property in ["title", "parentName", "parentid"]) |
|
201 do_check_eq(newrecord[property], folder[property]); |
|
202 |
|
203 _("Folders have high sort index to ensure they're synced first."); |
|
204 do_check_eq(newrecord.sortindex, 1000000); |
|
205 } finally { |
|
206 _("Clean up."); |
|
207 store.wipe(); |
|
208 run_next_test(); |
|
209 } |
|
210 }); |
|
211 |
|
212 add_test(function test_folder_createRecord() { |
|
213 try { |
|
214 _("Create a folder."); |
|
215 let folder1_id = PlacesUtils.bookmarks.createFolder( |
|
216 PlacesUtils.bookmarks.toolbarFolder, "Folder1", 0); |
|
217 let folder1_guid = store.GUIDForId(folder1_id); |
|
218 |
|
219 _("Create two bookmarks in that folder without assigning them GUIDs."); |
|
220 let bmk1_id = PlacesUtils.bookmarks.insertBookmark( |
|
221 folder1_id, fxuri, PlacesUtils.bookmarks.DEFAULT_INDEX, "Get Firefox!"); |
|
222 let bmk2_id = PlacesUtils.bookmarks.insertBookmark( |
|
223 folder1_id, tburi, PlacesUtils.bookmarks.DEFAULT_INDEX, "Get Thunderbird!"); |
|
224 |
|
225 _("Create a record for the folder and verify basic properties."); |
|
226 let record = store.createRecord(folder1_guid); |
|
227 do_check_true(record instanceof BookmarkFolder); |
|
228 do_check_eq(record.title, "Folder1"); |
|
229 do_check_eq(record.parentid, "toolbar"); |
|
230 do_check_eq(record.parentName, "Bookmarks Toolbar"); |
|
231 |
|
232 _("Verify the folder's children. Ensures that the bookmarks were given GUIDs."); |
|
233 let bmk1_guid = store.GUIDForId(bmk1_id); |
|
234 let bmk2_guid = store.GUIDForId(bmk2_id); |
|
235 do_check_eq(record.children.length, 2); |
|
236 do_check_eq(record.children[0], bmk1_guid); |
|
237 do_check_eq(record.children[1], bmk2_guid); |
|
238 |
|
239 } finally { |
|
240 _("Clean up."); |
|
241 store.wipe(); |
|
242 run_next_test(); |
|
243 } |
|
244 }); |
|
245 |
|
246 add_test(function test_deleted() { |
|
247 try { |
|
248 _("Create a bookmark that will be deleted."); |
|
249 let bmk1_id = PlacesUtils.bookmarks.insertBookmark( |
|
250 PlacesUtils.bookmarks.toolbarFolder, fxuri, |
|
251 PlacesUtils.bookmarks.DEFAULT_INDEX, "Get Firefox!"); |
|
252 let bmk1_guid = store.GUIDForId(bmk1_id); |
|
253 |
|
254 _("Delete the bookmark through the store."); |
|
255 let record = new PlacesItem("bookmarks", bmk1_guid); |
|
256 record.deleted = true; |
|
257 store.applyIncoming(record); |
|
258 |
|
259 _("Ensure it has been deleted."); |
|
260 let error; |
|
261 try { |
|
262 PlacesUtils.bookmarks.getBookmarkURI(bmk1_id); |
|
263 } catch(ex) { |
|
264 error = ex; |
|
265 } |
|
266 do_check_eq(error.result, Cr.NS_ERROR_ILLEGAL_VALUE); |
|
267 |
|
268 let newrec = store.createRecord(bmk1_guid); |
|
269 do_check_eq(newrec.deleted, true); |
|
270 |
|
271 } finally { |
|
272 _("Clean up."); |
|
273 store.wipe(); |
|
274 run_next_test(); |
|
275 } |
|
276 }); |
|
277 |
|
278 add_test(function test_move_folder() { |
|
279 try { |
|
280 _("Create two folders and a bookmark in one of them."); |
|
281 let folder1_id = PlacesUtils.bookmarks.createFolder( |
|
282 PlacesUtils.bookmarks.toolbarFolder, "Folder1", 0); |
|
283 let folder1_guid = store.GUIDForId(folder1_id); |
|
284 let folder2_id = PlacesUtils.bookmarks.createFolder( |
|
285 PlacesUtils.bookmarks.toolbarFolder, "Folder2", 0); |
|
286 let folder2_guid = store.GUIDForId(folder2_id); |
|
287 let bmk_id = PlacesUtils.bookmarks.insertBookmark( |
|
288 folder1_id, fxuri, PlacesUtils.bookmarks.DEFAULT_INDEX, "Get Firefox!"); |
|
289 let bmk_guid = store.GUIDForId(bmk_id); |
|
290 |
|
291 _("Get a record, reparent it and apply it to the store."); |
|
292 let record = store.createRecord(bmk_guid); |
|
293 do_check_eq(record.parentid, folder1_guid); |
|
294 record.parentid = folder2_guid; |
|
295 store.applyIncoming(record); |
|
296 |
|
297 _("Verify the new parent."); |
|
298 let new_folder_id = PlacesUtils.bookmarks.getFolderIdForItem(bmk_id); |
|
299 do_check_eq(store.GUIDForId(new_folder_id), folder2_guid); |
|
300 } finally { |
|
301 _("Clean up."); |
|
302 store.wipe(); |
|
303 run_next_test(); |
|
304 } |
|
305 }); |
|
306 |
|
307 add_test(function test_move_order() { |
|
308 // Make sure the tracker is turned on. |
|
309 Svc.Obs.notify("weave:engine:start-tracking"); |
|
310 try { |
|
311 _("Create two bookmarks"); |
|
312 let bmk1_id = PlacesUtils.bookmarks.insertBookmark( |
|
313 PlacesUtils.bookmarks.toolbarFolder, fxuri, |
|
314 PlacesUtils.bookmarks.DEFAULT_INDEX, "Get Firefox!"); |
|
315 let bmk1_guid = store.GUIDForId(bmk1_id); |
|
316 let bmk2_id = PlacesUtils.bookmarks.insertBookmark( |
|
317 PlacesUtils.bookmarks.toolbarFolder, tburi, |
|
318 PlacesUtils.bookmarks.DEFAULT_INDEX, "Get Thunderbird!"); |
|
319 let bmk2_guid = store.GUIDForId(bmk2_id); |
|
320 |
|
321 _("Verify order."); |
|
322 do_check_eq(PlacesUtils.bookmarks.getItemIndex(bmk1_id), 0); |
|
323 do_check_eq(PlacesUtils.bookmarks.getItemIndex(bmk2_id), 1); |
|
324 let toolbar = store.createRecord("toolbar"); |
|
325 do_check_eq(toolbar.children.length, 2); |
|
326 do_check_eq(toolbar.children[0], bmk1_guid); |
|
327 do_check_eq(toolbar.children[1], bmk2_guid); |
|
328 |
|
329 _("Move bookmarks around."); |
|
330 store._childrenToOrder = {}; |
|
331 toolbar.children = [bmk2_guid, bmk1_guid]; |
|
332 store.applyIncoming(toolbar); |
|
333 // Bookmarks engine does this at the end of _processIncoming |
|
334 tracker.ignoreAll = true; |
|
335 store._orderChildren(); |
|
336 tracker.ignoreAll = false; |
|
337 delete store._childrenToOrder; |
|
338 |
|
339 _("Verify new order."); |
|
340 do_check_eq(PlacesUtils.bookmarks.getItemIndex(bmk2_id), 0); |
|
341 do_check_eq(PlacesUtils.bookmarks.getItemIndex(bmk1_id), 1); |
|
342 |
|
343 } finally { |
|
344 Svc.Obs.notify("weave:engine:stop-tracking"); |
|
345 _("Clean up."); |
|
346 store.wipe(); |
|
347 run_next_test(); |
|
348 } |
|
349 }); |
|
350 |
|
351 add_test(function test_orphan() { |
|
352 try { |
|
353 |
|
354 _("Add a new bookmark locally."); |
|
355 let bmk1_id = PlacesUtils.bookmarks.insertBookmark( |
|
356 PlacesUtils.bookmarks.toolbarFolder, fxuri, |
|
357 PlacesUtils.bookmarks.DEFAULT_INDEX, "Get Firefox!"); |
|
358 let bmk1_guid = store.GUIDForId(bmk1_id); |
|
359 do_check_eq(PlacesUtils.bookmarks.getFolderIdForItem(bmk1_id), |
|
360 PlacesUtils.bookmarks.toolbarFolder); |
|
361 let error; |
|
362 try { |
|
363 PlacesUtils.annotations.getItemAnnotation(bmk1_id, PARENT_ANNO); |
|
364 } catch(ex) { |
|
365 error = ex; |
|
366 } |
|
367 do_check_eq(error.result, Cr.NS_ERROR_NOT_AVAILABLE); |
|
368 |
|
369 _("Apply a server record that is the same but refers to non-existent folder."); |
|
370 let record = store.createRecord(bmk1_guid); |
|
371 record.parentid = "non-existent"; |
|
372 store.applyIncoming(record); |
|
373 |
|
374 _("Verify that bookmark has been flagged as orphan, has not moved."); |
|
375 do_check_eq(PlacesUtils.bookmarks.getFolderIdForItem(bmk1_id), |
|
376 PlacesUtils.bookmarks.toolbarFolder); |
|
377 do_check_eq(PlacesUtils.annotations.getItemAnnotation(bmk1_id, PARENT_ANNO), |
|
378 "non-existent"); |
|
379 |
|
380 } finally { |
|
381 _("Clean up."); |
|
382 store.wipe(); |
|
383 run_next_test(); |
|
384 } |
|
385 }); |
|
386 |
|
387 add_test(function test_reparentOrphans() { |
|
388 try { |
|
389 let folder1_id = PlacesUtils.bookmarks.createFolder( |
|
390 PlacesUtils.bookmarks.toolbarFolder, "Folder1", 0); |
|
391 let folder1_guid = store.GUIDForId(folder1_id); |
|
392 |
|
393 _("Create a bogus orphan record and write the record back to the store to trigger _reparentOrphans."); |
|
394 PlacesUtils.annotations.setItemAnnotation( |
|
395 folder1_id, PARENT_ANNO, folder1_guid, 0, |
|
396 PlacesUtils.annotations.EXPIRE_NEVER); |
|
397 let record = store.createRecord(folder1_guid); |
|
398 record.title = "New title for Folder 1"; |
|
399 store._childrenToOrder = {}; |
|
400 store.applyIncoming(record); |
|
401 |
|
402 _("Verify that is has been marked as an orphan even though it couldn't be moved into itself."); |
|
403 do_check_eq(PlacesUtils.annotations.getItemAnnotation(folder1_id, PARENT_ANNO), |
|
404 folder1_guid); |
|
405 |
|
406 } finally { |
|
407 _("Clean up."); |
|
408 store.wipe(); |
|
409 run_next_test(); |
|
410 } |
|
411 }); |
|
412 |
|
413 // Tests Bug 806460, in which query records arrive with empty folder |
|
414 // names and missing bookmark URIs. |
|
415 add_test(function test_empty_query_doesnt_die() { |
|
416 let record = new BookmarkQuery("bookmarks", "8xoDGqKrXf1P"); |
|
417 record.folderName = ""; |
|
418 record.queryId = ""; |
|
419 record.parentName = "Toolbar"; |
|
420 record.parentid = "toolbar"; |
|
421 |
|
422 // These should not throw. |
|
423 store.applyIncoming(record); |
|
424 |
|
425 delete record.folderName; |
|
426 store.applyIncoming(record); |
|
427 |
|
428 run_next_test(); |
|
429 }); |
|
430 |
|
431 function run_test() { |
|
432 initTestLogging('Trace'); |
|
433 run_next_test(); |
|
434 } |