services/sync/tests/unit/test_bookmark_smart_bookmarks.js

branch
TOR_BUG_9701
changeset 15
b8a032363ba2
equal deleted inserted replaced
-1:000000000000 0:dd99e119d33e
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://gre/modules/Log.jsm");
6 Cu.import("resource://services-sync/engines.js");
7 Cu.import("resource://services-sync/engines/bookmarks.js");
8 Cu.import("resource://services-sync/service.js");
9 Cu.import("resource://services-sync/util.js");
10 Cu.import("resource://testing-common/services/sync/utils.js");
11
12 const SMART_BOOKMARKS_ANNO = "Places/SmartBookmark";
13 var IOService = Cc["@mozilla.org/network/io-service;1"]
14 .getService(Ci.nsIIOService);
15 ("http://www.mozilla.com", null, null);
16
17
18 Service.engineManager.register(BookmarksEngine);
19 let engine = Service.engineManager.get("bookmarks");
20 let store = engine._store;
21
22 // Clean up after other tests. Only necessary in XULRunner.
23 store.wipe();
24
25 function newSmartBookmark(parent, uri, position, title, queryID) {
26 let id = PlacesUtils.bookmarks.insertBookmark(parent, uri, position, title);
27 PlacesUtils.annotations.setItemAnnotation(id, SMART_BOOKMARKS_ANNO,
28 queryID, 0,
29 PlacesUtils.annotations.EXPIRE_NEVER);
30 return id;
31 }
32
33 function smartBookmarkCount() {
34 // We do it this way because PlacesUtils.annotations.getItemsWithAnnotation
35 // doesn't work the same (or at all?) between 3.6 and 4.0.
36 let out = {};
37 PlacesUtils.annotations.getItemsWithAnnotation(SMART_BOOKMARKS_ANNO, out);
38 return out.value;
39 }
40
41 function clearBookmarks() {
42 _("Cleaning up existing items.");
43 PlacesUtils.bookmarks.removeFolderChildren(PlacesUtils.bookmarks.bookmarksMenuFolder);
44 PlacesUtils.bookmarks.removeFolderChildren(PlacesUtils.bookmarks.tagsFolder);
45 PlacesUtils.bookmarks.removeFolderChildren(PlacesUtils.bookmarks.toolbarFolder);
46 PlacesUtils.bookmarks.removeFolderChildren(PlacesUtils.bookmarks.unfiledBookmarksFolder);
47 startCount = smartBookmarkCount();
48 }
49
50 function serverForFoo(engine) {
51 return serverForUsers({"foo": "password"}, {
52 meta: {global: {engines: {bookmarks: {version: engine.version,
53 syncID: engine.syncID}}}},
54 bookmarks: {}
55 });
56 }
57
58 // Verify that Places smart bookmarks have their annotation uploaded and
59 // handled locally.
60 add_test(function test_annotation_uploaded() {
61 let server = serverForFoo(engine);
62 new SyncTestingInfrastructure(server.server);
63
64 let startCount = smartBookmarkCount();
65
66 _("Start count is " + startCount);
67
68 if (startCount > 0) {
69 // This can happen in XULRunner.
70 clearBookmarks();
71 _("Start count is now " + startCount);
72 }
73
74 _("Create a smart bookmark in the toolbar.");
75 let parent = PlacesUtils.toolbarFolderId;
76 let uri =
77 Utils.makeURI("place:sort=" +
78 Ci.nsINavHistoryQueryOptions.SORT_BY_VISITCOUNT_DESCENDING +
79 "&maxResults=10");
80 let title = "Most Visited";
81
82 let mostVisitedID = newSmartBookmark(parent, uri, -1, title, "MostVisited");
83
84 _("New item ID: " + mostVisitedID);
85 do_check_true(!!mostVisitedID);
86
87 let annoValue = PlacesUtils.annotations.getItemAnnotation(mostVisitedID,
88 SMART_BOOKMARKS_ANNO);
89 _("Anno: " + annoValue);
90 do_check_eq("MostVisited", annoValue);
91
92 let guid = store.GUIDForId(mostVisitedID);
93 _("GUID: " + guid);
94 do_check_true(!!guid);
95
96 _("Create record object and verify that it's sane.");
97 let record = store.createRecord(guid);
98 do_check_true(record instanceof Bookmark);
99 do_check_true(record instanceof BookmarkQuery);
100
101 do_check_eq(record.bmkUri, uri.spec);
102
103 _("Make sure the new record carries with it the annotation.");
104 do_check_eq("MostVisited", record.queryId);
105
106 _("Our count has increased since we started.");
107 do_check_eq(smartBookmarkCount(), startCount + 1);
108
109 _("Sync record to the server.");
110 let collection = server.user("foo").collection("bookmarks");
111
112 try {
113 engine.sync();
114 let wbos = collection.keys(function (id) {
115 return ["menu", "toolbar", "mobile"].indexOf(id) == -1;
116 });
117 do_check_eq(wbos.length, 1);
118
119 _("Verify that the server WBO has the annotation.");
120 let serverGUID = wbos[0];
121 do_check_eq(serverGUID, guid);
122 let serverWBO = collection.wbo(serverGUID);
123 do_check_true(!!serverWBO);
124 let body = JSON.parse(JSON.parse(serverWBO.payload).ciphertext);
125 do_check_eq(body.queryId, "MostVisited");
126
127 _("We still have the right count.");
128 do_check_eq(smartBookmarkCount(), startCount + 1);
129
130 _("Clear local records; now we can't find it.");
131
132 // "Clear" by changing attributes: if we delete it, apparently it sticks
133 // around as a deleted record...
134 PlacesUtils.bookmarks.setItemTitle(mostVisitedID, "Not Most Visited");
135 PlacesUtils.bookmarks.changeBookmarkURI(
136 mostVisitedID, Utils.makeURI("http://something/else"));
137 PlacesUtils.annotations.removeItemAnnotation(mostVisitedID,
138 SMART_BOOKMARKS_ANNO);
139 store.wipe();
140 engine.resetClient();
141 do_check_eq(smartBookmarkCount(), startCount);
142
143 _("Sync. Verify that the downloaded record carries the annotation.");
144 engine.sync();
145
146 _("Verify that the Places DB now has an annotated bookmark.");
147 _("Our count has increased again.");
148 do_check_eq(smartBookmarkCount(), startCount + 1);
149
150 _("Find by GUID and verify that it's annotated.");
151 let newID = store.idForGUID(serverGUID);
152 let newAnnoValue = PlacesUtils.annotations.getItemAnnotation(
153 newID, SMART_BOOKMARKS_ANNO);
154 do_check_eq(newAnnoValue, "MostVisited");
155 do_check_eq(PlacesUtils.bookmarks.getBookmarkURI(newID).spec, uri.spec);
156
157 _("Test updating.");
158 let newRecord = store.createRecord(serverGUID);
159 do_check_eq(newRecord.queryId, newAnnoValue);
160 newRecord.queryId = "LeastVisited";
161 store.update(newRecord);
162 do_check_eq("LeastVisited", PlacesUtils.annotations.getItemAnnotation(
163 newID, SMART_BOOKMARKS_ANNO));
164
165
166 } finally {
167 // Clean up.
168 store.wipe();
169 Svc.Prefs.resetBranch("");
170 Service.recordManager.clearCache();
171 server.stop(run_next_test);
172 }
173 });
174
175 add_test(function test_smart_bookmarks_duped() {
176 let server = serverForFoo(engine);
177 new SyncTestingInfrastructure(server.server);
178
179 let parent = PlacesUtils.toolbarFolderId;
180 let uri =
181 Utils.makeURI("place:sort=" +
182 Ci.nsINavHistoryQueryOptions.SORT_BY_VISITCOUNT_DESCENDING +
183 "&maxResults=10");
184 let title = "Most Visited";
185 let mostVisitedID = newSmartBookmark(parent, uri, -1, title, "MostVisited");
186 let mostVisitedGUID = store.GUIDForId(mostVisitedID);
187
188 let record = store.createRecord(mostVisitedGUID);
189
190 _("Prepare sync.");
191 let collection = server.user("foo").collection("bookmarks");
192
193 try {
194 engine._syncStartup();
195
196 _("Verify that mapDupe uses the anno, discovering a dupe regardless of URI.");
197 do_check_eq(mostVisitedGUID, engine._mapDupe(record));
198
199 record.bmkUri = "http://foo/";
200 do_check_eq(mostVisitedGUID, engine._mapDupe(record));
201 do_check_neq(PlacesUtils.bookmarks.getBookmarkURI(mostVisitedID).spec,
202 record.bmkUri);
203
204 _("Verify that different annos don't dupe.");
205 let other = new BookmarkQuery("bookmarks", "abcdefabcdef");
206 other.queryId = "LeastVisited";
207 other.parentName = "Bookmarks Toolbar";
208 other.bmkUri = "place:foo";
209 other.title = "";
210 do_check_eq(undefined, engine._findDupe(other));
211
212 _("Handle records without a queryId entry.");
213 record.bmkUri = uri;
214 delete record.queryId;
215 do_check_eq(mostVisitedGUID, engine._mapDupe(record));
216
217 engine._syncFinish();
218
219 } finally {
220 // Clean up.
221 store.wipe();
222 server.stop(do_test_finished);
223 Svc.Prefs.resetBranch("");
224 Service.recordManager.clearCache();
225 }
226 });
227
228 function run_test() {
229 initTestLogging("Trace");
230 Log.repository.getLogger("Sync.Engine.Bookmarks").level = Log.Level.Trace;
231
232 generateNewKeys(Service.collectionKeys);
233
234 run_next_test();
235 }

mercurial