Merge lp:~jamesh/bindwood/migration into lp:bindwood
- migration
- Merge into trunk
Status: | Merged |
---|---|
Approved by: | James Henstridge |
Approved revision: | 41 |
Merged at revision: | 40 |
Proposed branch: | lp:~jamesh/bindwood/migration |
Merge into: | lp:bindwood |
Prerequisite: | lp:~jamesh/bindwood/switch-to-new-synchroniser |
Diff against target: |
1134 lines (+736/-112) 9 files modified
modules/bindwood.jsm (+0/-111) modules/couch.jsm (+2/-1) modules/migration.jsm (+248/-0) modules/sync.jsm (+18/-0) mozmill/shared-modules/bookmarks.js (+7/-0) mozmill/tests/test_migration.js (+425/-0) mozmill/tests/test_sync_all.js (+14/-0) mozmill/tests/test_sync_from_couch.js (+17/-0) mozmill/tests/test_sync_to_couch.js (+5/-0) |
To merge this branch: | bzr merge lp:~jamesh/bindwood/migration |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Eric Casteleijn (community) | Approve | ||
Manuel de la Peña (community) | Approve | ||
Review via email: mp+52193@code.launchpad.net |
Commit message
Migration code to upgrade databases from Bindwood 0.4.x and 1.0.x schemas.
Description of the change
Add code to migrate old Bindwood bookmarks over to the new schema.
We determine the schema version like so:
* If there is no root_$profile document, assume we're using the
0.4.x schema (which I call version 0).
* If there is a root_$profile document but has no record_
assume we're using the 1.0.x schema (which I call version 1).
* If there is a root_$profile document and it has record_
assume it is equal to the schema version.
This gives us a way to detect future formats without much trouble.
I don't have code to convert from version 0, but instead rely on the ability to rebuild the database from Firefox's local places database.
I've also added a few attributes that will make it easier to implement a duplicate detection algorithm:
* parent_title: the title of the parent folder (combine this with
other bookmark data to detect duplicates).
* position: the numeric index of a separator (provides a way to
distinguish different separators in a folder).
Manuel de la Peña (mandel) : | # |
Ubuntu One Auto Pilot (otto-pilot) wrote : | # |
The prerequisite lp:~jamesh/bindwood/switch-to-new-synchroniser has not yet been merged into lp:bindwood.
Preview Diff
1 | === modified file 'modules/bindwood.jsm' | |||
2 | --- modules/bindwood.jsm 2011-03-04 13:02:54 +0000 | |||
3 | +++ modules/bindwood.jsm 2011-03-04 13:02:54 +0000 | |||
4 | @@ -169,115 +169,4 @@ | |||
5 | 169 | Log.exception("Problem setting up repeater.", e); | 169 | Log.exception("Problem setting up repeater.", e); |
6 | 170 | } | 170 | } |
7 | 171 | }, | 171 | }, |
8 | 172 | |||
9 | 173 | migrateOlderBookmarkRecords: function() { | ||
10 | 174 | Log.debug( | ||
11 | 175 | "We're an older client. " + | ||
12 | 176 | "Let's migrate the remote records and re-sync."); | ||
13 | 177 | |||
14 | 178 | var additional = []; | ||
15 | 179 | var all_docs = Bindwood.couch.view("bookmarks/profile", | ||
16 | 180 | { | ||
17 | 181 | startkey: Bindwood.currentProfile, | ||
18 | 182 | endkey: Bindwood.currentProfile | ||
19 | 183 | }); | ||
20 | 184 | var rows = all_docs.rows; | ||
21 | 185 | |||
22 | 186 | // Pull all records from Couch, and for each: | ||
23 | 187 | |||
24 | 188 | for (var i = 0; i < rows.length; i++) { | ||
25 | 189 | var row = rows[i]; | ||
26 | 190 | Log.debug("Got a row: " + row); | ||
27 | 191 | var id = row.id; | ||
28 | 192 | Log.debug("Got an id: " + id); | ||
29 | 193 | var doc = Bindwood.couch.open(id); | ||
30 | 194 | Log.debug("Got a doc: " + doc); | ||
31 | 195 | |||
32 | 196 | if (doc.record_type_version >= 1) { | ||
33 | 197 | Log.debug( | ||
34 | 198 | "Record is already migrated Skipping..."); | ||
35 | 199 | continue; | ||
36 | 200 | } | ||
37 | 201 | |||
38 | 202 | // get the uuid off the bookmark. | ||
39 | 203 | var old_uuid = doc.application_annotations.Firefox.uuid; | ||
40 | 204 | Log.debug( | ||
41 | 205 | "Got the old uuid from the record: " + old_uuid); | ||
42 | 206 | // look up itemId by uuid | ||
43 | 207 | // XXX: This probably needs to be made more robust | ||
44 | 208 | var itemId = Bindwood.itemIdForUUID(old_uuid); | ||
45 | 209 | Log.debug( | ||
46 | 210 | "Found its local itemID from the map: " + itemId); | ||
47 | 211 | // annotate the itemId with the document's _id | ||
48 | 212 | Bindwood.annotateItemWithUUID(itemId, id); | ||
49 | 213 | Log.debug( | ||
50 | 214 | "Annotating the item's uuid with the document's actual id"); | ||
51 | 215 | // delete the uuid field off the record | ||
52 | 216 | delete doc.application_annotations.Firefox.uuid; | ||
53 | 217 | Log.debug("Deleted the document's uuid annotation"); | ||
54 | 218 | // delete the folder field off the record | ||
55 | 219 | delete doc.application_annotations.Firefox.folder; | ||
56 | 220 | Log.debug("Deleted the document's folder annotation"); | ||
57 | 221 | |||
58 | 222 | if (doc.deleted) { | ||
59 | 223 | Log.debug( | ||
60 | 224 | "The document was flagged as deleted, cleaning up."); | ||
61 | 225 | // swap .deleted for conventional .deleted | ||
62 | 226 | if (!doc.application_annotations) { | ||
63 | 227 | doc.application_annotations = {}; | ||
64 | 228 | } | ||
65 | 229 | if (!doc.application_annotations['Ubuntu One']) { | ||
66 | 230 | doc.application_annotations['Ubuntu One'] = {}; | ||
67 | 231 | } | ||
68 | 232 | if (!doc.application_annotations['Ubuntu One'].private_application_annotations) { | ||
69 | 233 | doc.application_annotations['Ubuntu One'].private_application_annotations = {}; | ||
70 | 234 | } | ||
71 | 235 | doc.application_annotations['Ubuntu One'].private_application_annotations.deleted = true; | ||
72 | 236 | Log.debug( | ||
73 | 237 | "Moved deleted flag into private application annotations."); | ||
74 | 238 | delete doc.deleted; | ||
75 | 239 | Log.debug("Deleted the top-level .deleted flag."); | ||
76 | 240 | } | ||
77 | 241 | |||
78 | 242 | // update the document's record_type_version | ||
79 | 243 | doc.record_type_version = 1; | ||
80 | 244 | Log.debug("Set the schema version to 1"); | ||
81 | 245 | |||
82 | 246 | // Ensure we're dealing with the proper record type on Migrate. | ||
83 | 247 | doc = Bindwood.decorateRecordByType(doc, itemId); | ||
84 | 248 | |||
85 | 249 | // add to additional | ||
86 | 250 | additional.push(doc); | ||
87 | 251 | Log.debug( | ||
88 | 252 | "Adding this doc to the stack of addition docs to push back."); | ||
89 | 253 | } | ||
90 | 254 | |||
91 | 255 | for (var i = 0; i < additional.length; i++) { | ||
92 | 256 | var doc = additional[i]; | ||
93 | 257 | Log.debug( | ||
94 | 258 | "Preparing to push back " + doc.title || doc.record_type); | ||
95 | 259 | // Ensure that any remote folders have their .children | ||
96 | 260 | // populated, and in particular make sure that we've already | ||
97 | 261 | // modified their children's annotations/uuids | ||
98 | 262 | if (doc.record_type == Bindwood.TYPE_FOLDER) { | ||
99 | 263 | // XXX: This probably needs to be made more robust | ||
100 | 264 | var itemId = Bindwood.itemIdForUUID(doc._id); | ||
101 | 265 | doc.children = Bindwood.getUUIDsFromFolder(itemId); | ||
102 | 266 | Log.debug( | ||
103 | 267 | "Folder needed updating, calculated children: " + | ||
104 | 268 | doc.children); | ||
105 | 269 | } | ||
106 | 270 | |||
107 | 271 | try { | ||
108 | 272 | var response = Bindwood.couch.save(doc); | ||
109 | 273 | // We can avoid having to process this revision when we | ||
110 | 274 | // pull it later | ||
111 | 275 | Bindwood.seen_revisions[response.rev] = true; | ||
112 | 276 | } catch(e) { | ||
113 | 277 | Log.exception( | ||
114 | 278 | "Problem saving record to CouchDB; record is " + | ||
115 | 279 | JSON.stringify(doc + ": ", e)); | ||
116 | 280 | } | ||
117 | 281 | } | ||
118 | 282 | }, | ||
119 | 283 | }; | 172 | }; |
120 | 284 | 173 | ||
121 | === modified file 'modules/couch.jsm' | |||
122 | --- modules/couch.jsm 2011-02-04 06:03:15 +0000 | |||
123 | +++ modules/couch.jsm 2011-03-04 13:02:54 +0000 | |||
124 | @@ -100,7 +100,7 @@ | |||
125 | 100 | if (docs[i]._id == undefined) | 100 | if (docs[i]._id == undefined) |
126 | 101 | newCount++; | 101 | newCount++; |
127 | 102 | } | 102 | } |
129 | 103 | var newUuids = CouchDB.newUuids(docs.length); | 103 | var newUuids = CouchDB.newUuids(newCount); |
130 | 104 | var newCount = 0; | 104 | var newCount = 0; |
131 | 105 | for (var i=0; i<docs.length; i++) { | 105 | for (var i=0; i<docs.length; i++) { |
132 | 106 | if (docs[i]._id == undefined) | 106 | if (docs[i]._id == undefined) |
133 | @@ -112,6 +112,7 @@ | |||
134 | 112 | json[option] = options[option]; | 112 | json[option] = options[option]; |
135 | 113 | } | 113 | } |
136 | 114 | this.last_req = this.request("POST", this.uri + "_bulk_docs", { | 114 | this.last_req = this.request("POST", this.uri + "_bulk_docs", { |
137 | 115 | headers: {"Content-Type": "application/json"}, | ||
138 | 115 | body: JSON.stringify(json) | 116 | body: JSON.stringify(json) |
139 | 116 | }); | 117 | }); |
140 | 117 | if (this.last_req.status == 417) { | 118 | if (this.last_req.status == 417) { |
141 | 118 | 119 | ||
142 | === added file 'modules/migration.jsm' | |||
143 | --- modules/migration.jsm 1970-01-01 00:00:00 +0000 | |||
144 | +++ modules/migration.jsm 2011-03-04 13:02:54 +0000 | |||
145 | @@ -0,0 +1,248 @@ | |||
146 | 1 | /* | ||
147 | 2 | * Copyright 2009-2011 Canonical Ltd. | ||
148 | 3 | * | ||
149 | 4 | * This program is free software: you can redistribute it and/or modify it | ||
150 | 5 | * under the terms of the GNU General Public License version 3, as published | ||
151 | 6 | * by the Free Software Foundation. | ||
152 | 7 | * | ||
153 | 8 | * This program is distributed in the hope that it will be useful, but | ||
154 | 9 | * WITHOUT ANY WARRANTY; without even the implied warranties of | ||
155 | 10 | * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR | ||
156 | 11 | * PURPOSE. See the GNU General Public License for more details. | ||
157 | 12 | * | ||
158 | 13 | * You should have received a copy of the GNU General Public License along | ||
159 | 14 | * with this program. If not, see <http://www.gnu.org/licenses/>. | ||
160 | 15 | */ | ||
161 | 16 | |||
162 | 17 | const EXPORTED_SYMBOLS = ['SchemaMigration']; | ||
163 | 18 | |||
164 | 19 | const Cu = Components.utils; | ||
165 | 20 | |||
166 | 21 | Cu.import("resource://bindwood/logging.jsm"); | ||
167 | 22 | |||
168 | 23 | |||
169 | 24 | function SchemaMigration(couch, profile) { | ||
170 | 25 | this.couch = couch; | ||
171 | 26 | this.profile = profile; | ||
172 | 27 | } | ||
173 | 28 | |||
174 | 29 | SchemaMigration.prototype = { | ||
175 | 30 | |||
176 | 31 | get_schema_version: function() { | ||
177 | 32 | var doc = this.couch.open('root_' + this.profile); | ||
178 | 33 | |||
179 | 34 | if (!doc) { | ||
180 | 35 | // If there is no root document, we're dealing with the | ||
181 | 36 | // original Bindwood datbase schema. | ||
182 | 37 | return 0; | ||
183 | 38 | } | ||
184 | 39 | // If the root document does not have a record_type_version, | ||
185 | 40 | // assume it is the second schema version. | ||
186 | 41 | if (!doc.record_type_version) { | ||
187 | 42 | return 1; | ||
188 | 43 | } | ||
189 | 44 | // Otherwise, use the value of record_type_version. | ||
190 | 45 | return doc.record_type_version; | ||
191 | 46 | }, | ||
192 | 47 | |||
193 | 48 | upgrade: function() { | ||
194 | 49 | var schema_version = this.get_schema_version(); | ||
195 | 50 | Log.debug("Current schema version is " + schema_version); | ||
196 | 51 | switch (schema_version) { | ||
197 | 52 | case 0: | ||
198 | 53 | // Haven't written migration code for this format, so just | ||
199 | 54 | // wipe out the bookmarks and assume that we can rebuild | ||
200 | 55 | // from the local places database. | ||
201 | 56 | this.wipe_bookmarks(); | ||
202 | 57 | return true; | ||
203 | 58 | case 1: | ||
204 | 59 | this.upgrade_1_to_2(); | ||
205 | 60 | return true; | ||
206 | 61 | case 2: | ||
207 | 62 | // Nothing to be done: we're at the most recent version. | ||
208 | 63 | return false; | ||
209 | 64 | default: | ||
210 | 65 | Log.error("Unknown schema version " + schema_version); | ||
211 | 66 | return false; | ||
212 | 67 | } | ||
213 | 68 | }, | ||
214 | 69 | |||
215 | 70 | wipe_bookmarks: function() { | ||
216 | 71 | Log.debug("Wiping all bookmarks for profile " + this.profile); | ||
217 | 72 | var result = this.couch.view("bindwood/bookmarks", { | ||
218 | 73 | key: this.profile, | ||
219 | 74 | include_docs: true, | ||
220 | 75 | }); | ||
221 | 76 | var changes = []; | ||
222 | 77 | for each (var row in result.rows) { | ||
223 | 78 | var doc = row.doc; | ||
224 | 79 | changes.push({ | ||
225 | 80 | _id: doc._id, | ||
226 | 81 | _rev: doc._rev, | ||
227 | 82 | _deleted: true | ||
228 | 83 | }); | ||
229 | 84 | } | ||
230 | 85 | // Delete all the bookmarks. | ||
231 | 86 | this.couch.bulkSave(changes); | ||
232 | 87 | }, | ||
233 | 88 | |||
234 | 89 | /* The format used by Bindwood 0.4.2. Bookmarks were represented as: | ||
235 | 90 | * | ||
236 | 91 | * { | ||
237 | 92 | * _id: '...', | ||
238 | 93 | * record_type: 'http://www.freedesktop.org/wiki/Specifications/desktopcouch/bookmark', | ||
239 | 94 | * title: 'Bookmark title', | ||
240 | 95 | * uri: 'http://www.example.com/', | ||
241 | 96 | * application_annotations: { | ||
242 | 97 | * Firefox: { | ||
243 | 98 | * uuid: '...', // This is the UUID associated with the local item. | ||
244 | 99 | * folder: 'Title of parent folder', | ||
245 | 100 | * profile: 'profile name' | ||
246 | 101 | * } | ||
247 | 102 | * } | ||
248 | 103 | * } | ||
249 | 104 | * | ||
250 | 105 | * Folders and separators had the appropriate record types, and | ||
251 | 106 | * had no URI property. Folder child ordering is not stored | ||
252 | 107 | * anywhere. | ||
253 | 108 | * | ||
254 | 109 | * There is no special handling of livemarks. They are stored as | ||
255 | 110 | * folders, and their children are also stored. | ||
256 | 111 | * | ||
257 | 112 | * The special parent names "toolbarFolder", "bookmarksMenuFolder" | ||
258 | 113 | * and "unfiledBookmarksFolder" were used to represent items at | ||
259 | 114 | * the top levels of each folder hierarchy. | ||
260 | 115 | */ | ||
261 | 116 | |||
262 | 117 | /* The format used by Bindwood 1.0.x. Bookmarks look like this: | ||
263 | 118 | * | ||
264 | 119 | * { | ||
265 | 120 | * _id: '...', // This is the UUID associated with the local item. | ||
266 | 121 | * record_type: 'http://www.freedesktop.org/wiki/Specifications/desktopcouch/bookmark', | ||
267 | 122 | * record_type_version: 1, | ||
268 | 123 | * title: 'Bookmark title', | ||
269 | 124 | * uri: 'http://www.example.com/', | ||
270 | 125 | * application_annotations: { | ||
271 | 126 | * Firefox: { | ||
272 | 127 | * profile: 'profile name' | ||
273 | 128 | * last_modified: ..., // time in microseconds since epoch | ||
274 | 129 | * } | ||
275 | 130 | * } | ||
276 | 131 | * } | ||
277 | 132 | * | ||
278 | 133 | * Folders contain a list of the IDs of their children (the | ||
279 | 134 | * opposite of the 0.4.2 format), which also acts as a way to | ||
280 | 135 | * store the child ordering. | ||
281 | 136 | * | ||
282 | 137 | * Livemarks are stored with their own record type. They look | ||
283 | 138 | * similar to normal bookmarks, but store site_uri and feed_uri | ||
284 | 139 | * instead of a single bookmark URI. | ||
285 | 140 | */ | ||
286 | 141 | upgrade_1_to_2: function() { | ||
287 | 142 | Log.debug("Upgrading bookmarks for profile " + this.profile + | ||
288 | 143 | " from schema v1 to v2"); | ||
289 | 144 | var result = this.couch.view("bindwood/bookmarks", { | ||
290 | 145 | key: this.profile, | ||
291 | 146 | include_docs: true, | ||
292 | 147 | }); | ||
293 | 148 | |||
294 | 149 | var changes = []; | ||
295 | 150 | |||
296 | 151 | // Build a map of document IDs to the documents they reflect. | ||
297 | 152 | var docs_by_id = {}; | ||
298 | 153 | for each (var row in result.rows) { | ||
299 | 154 | docs_by_id[row.id] = row.doc; | ||
300 | 155 | } | ||
301 | 156 | |||
302 | 157 | // Fix up children of the root document. The children (which | ||
303 | 158 | // represent the toolbar, bookmarks menu and unfiled bookmarks | ||
304 | 159 | // folders) should be renamed to fixed identifiers. | ||
305 | 160 | var root_doc = docs_by_id['root_' + this.profile]; | ||
306 | 161 | root_doc.record_type = 'http://www.freedesktop.org/wiki/Specifications/desktopcouch/folder'; | ||
307 | 162 | var expected_children = [ | ||
308 | 163 | 'toolbar_' + this.profile, | ||
309 | 164 | 'menu_' + this.profile, | ||
310 | 165 | 'unfiled_' + this.profile]; | ||
311 | 166 | for (var i = 0; i < expected_children.length; i++) { | ||
312 | 167 | var old_id = root_doc.children[i]; | ||
313 | 168 | var new_id = expected_children[i]; | ||
314 | 169 | // Existing document has expected name. | ||
315 | 170 | if (old_id == new_id) { | ||
316 | 171 | continue; | ||
317 | 172 | } | ||
318 | 173 | var doc = docs_by_id[old_id]; | ||
319 | 174 | delete docs_by_id[old_id]; | ||
320 | 175 | |||
321 | 176 | // Schedule deletion of old document | ||
322 | 177 | changes.push({ | ||
323 | 178 | _id: doc._id, | ||
324 | 179 | _rev: doc._rev, | ||
325 | 180 | _deleted: true | ||
326 | 181 | }); | ||
327 | 182 | doc._id = new_id; | ||
328 | 183 | delete doc._rev; | ||
329 | 184 | docs_by_id[new_id] = doc; | ||
330 | 185 | root_doc.children[i] = new_id; | ||
331 | 186 | } | ||
332 | 187 | |||
333 | 188 | // Walk the bookmarks tree from the root node to determine | ||
334 | 189 | // which documents are reachable, and build up a parent map. | ||
335 | 190 | var reachable = {}; | ||
336 | 191 | var parents_by_id = {}; | ||
337 | 192 | |||
338 | 193 | var remaining = [root_doc]; | ||
339 | 194 | reachable[root_doc._id] = true; | ||
340 | 195 | while (remaining.length > 0) { | ||
341 | 196 | var doc = remaining.pop(); | ||
342 | 197 | for each (var child_id in doc.children) { | ||
343 | 198 | parents_by_id[child_id] = doc; | ||
344 | 199 | reachable[child_id] = true; | ||
345 | 200 | |||
346 | 201 | var child_doc = docs_by_id[child_id]; | ||
347 | 202 | if (child_doc && child_doc.record_type == 'http://www.freedesktop.org/wiki/Specifications/desktopcouch/folder') { | ||
348 | 203 | remaining.push(child_doc); | ||
349 | 204 | } | ||
350 | 205 | } | ||
351 | 206 | } | ||
352 | 207 | |||
353 | 208 | // Now update the documents. | ||
354 | 209 | for each (var doc in docs_by_id) { | ||
355 | 210 | // If the document can not be reached from the root, then | ||
356 | 211 | // it does not belong in the document tree. | ||
357 | 212 | if (!reachable[doc._id]) { | ||
358 | 213 | Log.debug("Deleting bookmark " + doc._id + | ||
359 | 214 | " is not reachable from root."); | ||
360 | 215 | changes.push({ | ||
361 | 216 | _id: doc._id, | ||
362 | 217 | _rev: doc._rev, | ||
363 | 218 | _deleted: true | ||
364 | 219 | }); | ||
365 | 220 | continue; | ||
366 | 221 | } | ||
367 | 222 | |||
368 | 223 | doc.record_type_version = 2; | ||
369 | 224 | var parent_doc = parents_by_id[doc._id] | ||
370 | 225 | if (parent_doc) { | ||
371 | 226 | doc.parent_guid = parent_doc._id; | ||
372 | 227 | doc.parent_title = parent_doc.title; | ||
373 | 228 | } | ||
374 | 229 | |||
375 | 230 | // Bindwood 1.0.x would store a lot of useless data in the | ||
376 | 231 | // Firefox section of the document (basically anything | ||
377 | 232 | // that triggered an onItemChanged callback). Keep only | ||
378 | 233 | // the information we care about. | ||
379 | 234 | var old_annotations = doc.application_annotations.Firefox; | ||
380 | 235 | var new_annotations = { | ||
381 | 236 | profile: old_annotations.profile, | ||
382 | 237 | last_modified: old_annotations.last_modified | ||
383 | 238 | }; | ||
384 | 239 | doc.application_annotations.Firefox = new_annotations; | ||
385 | 240 | |||
386 | 241 | changes.push(doc); | ||
387 | 242 | } | ||
388 | 243 | // Now push the updates back to CouchDB. | ||
389 | 244 | Log.debug("Saving modifications to database."); | ||
390 | 245 | this.couch.bulkSave(changes); | ||
391 | 246 | Log.debug("Done."); | ||
392 | 247 | } | ||
393 | 248 | }; | ||
394 | 0 | 249 | ||
395 | === modified file 'modules/sync.jsm' | |||
396 | --- modules/sync.jsm 2011-03-04 13:02:54 +0000 | |||
397 | +++ modules/sync.jsm 2011-03-04 13:02:54 +0000 | |||
398 | @@ -22,6 +22,7 @@ | |||
399 | 22 | const Cu = Components.utils; | 22 | const Cu = Components.utils; |
400 | 23 | 23 | ||
401 | 24 | Cu.import("resource://bindwood/logging.jsm"); | 24 | Cu.import("resource://bindwood/logging.jsm"); |
402 | 25 | Cu.import("resource://bindwood/migration.jsm"); | ||
403 | 25 | 26 | ||
404 | 26 | const GUID_ANNOTATION = "bindwood/uuid"; | 27 | const GUID_ANNOTATION = "bindwood/uuid"; |
405 | 27 | const PARENT_ANNOTATION = "bindwood/parent"; | 28 | const PARENT_ANNOTATION = "bindwood/parent"; |
406 | @@ -33,6 +34,8 @@ | |||
407 | 33 | const TYPE_FEED = RECORD_PREFIX + "feed"; | 34 | const TYPE_FEED = RECORD_PREFIX + "feed"; |
408 | 34 | const TYPE_SEPARATOR = RECORD_PREFIX + "separator"; | 35 | const TYPE_SEPARATOR = RECORD_PREFIX + "separator"; |
409 | 35 | 36 | ||
410 | 37 | const RECORD_TYPE_VERSION = 2; | ||
411 | 38 | |||
412 | 36 | var bookmarksService = Cc["@mozilla.org/browser/nav-bookmarks-service;1"] | 39 | var bookmarksService = Cc["@mozilla.org/browser/nav-bookmarks-service;1"] |
413 | 37 | .getService(Ci.nsINavBookmarksService); | 40 | .getService(Ci.nsINavBookmarksService); |
414 | 38 | var livemarkService = Cc["@mozilla.org/browser/livemark-service;2"] | 41 | var livemarkService = Cc["@mozilla.org/browser/livemark-service;2"] |
415 | @@ -62,6 +65,7 @@ | |||
416 | 62 | Log.debug("Initialising synchroniser."); | 65 | Log.debug("Initialising synchroniser."); |
417 | 63 | this.ensureDatabase(); | 66 | this.ensureDatabase(); |
418 | 64 | this.ensureCouchViews(); | 67 | this.ensureCouchViews(); |
419 | 68 | this.maybeMigrateData(); | ||
420 | 65 | this.first_push = true; | 69 | this.first_push = true; |
421 | 66 | this.observer = new BookmarksObserver(this); | 70 | this.observer = new BookmarksObserver(this); |
422 | 67 | bookmarksService.addObserver(this.observer, false); | 71 | bookmarksService.addObserver(this.observer, false); |
423 | @@ -132,6 +136,16 @@ | |||
424 | 132 | } | 136 | } |
425 | 133 | }, | 137 | }, |
426 | 134 | 138 | ||
427 | 139 | maybeMigrateData: function() { | ||
428 | 140 | migration = new SchemaMigration(this.couch, this.profile); | ||
429 | 141 | |||
430 | 142 | if (migration.upgrade()) { | ||
431 | 143 | Log.debug("Schema was upgraded, so resetting last known " + | ||
432 | 144 | "sequence number."); | ||
433 | 145 | this.last_seq = 0; | ||
434 | 146 | } | ||
435 | 147 | }, | ||
436 | 148 | |||
437 | 135 | set_guid: function(item_id, guid) { | 149 | set_guid: function(item_id, guid) { |
438 | 136 | // If the item has already been annotated with a GUID, clear | 150 | // If the item has already been annotated with a GUID, clear |
439 | 137 | // the old GUID mapping from our cache. | 151 | // the old GUID mapping from our cache. |
440 | @@ -543,6 +557,7 @@ | |||
441 | 543 | } | 557 | } |
442 | 544 | } | 558 | } |
443 | 545 | 559 | ||
444 | 560 | _setattr(doc, "record_type_version", RECORD_TYPE_VERSION); | ||
445 | 546 | if (!doc.application_annotations) | 561 | if (!doc.application_annotations) |
446 | 547 | doc.application_annotations = {}; | 562 | doc.application_annotations = {}; |
447 | 548 | if (!doc.application_annotations.Firefox) | 563 | if (!doc.application_annotations.Firefox) |
448 | @@ -553,6 +568,8 @@ | |||
449 | 553 | if (parent_id > 0) { | 568 | if (parent_id > 0) { |
450 | 554 | var parent_guid = this.guid_from_id(parent_id); | 569 | var parent_guid = this.guid_from_id(parent_id); |
451 | 555 | _setattr(doc, "parent_guid", parent_guid); | 570 | _setattr(doc, "parent_guid", parent_guid); |
452 | 571 | _setattr( | ||
453 | 572 | doc, "parent_title", bookmarksService.getItemTitle(parent_id)); | ||
454 | 556 | } | 573 | } |
455 | 557 | switch (item_type) { | 574 | switch (item_type) { |
456 | 558 | case bookmarksService.TYPE_BOOKMARK: | 575 | case bookmarksService.TYPE_BOOKMARK: |
457 | @@ -579,6 +596,7 @@ | |||
458 | 579 | break; | 596 | break; |
459 | 580 | case bookmarksService.TYPE_SEPARATOR: | 597 | case bookmarksService.TYPE_SEPARATOR: |
460 | 581 | _setattr(doc, "record_type", TYPE_SEPARATOR); | 598 | _setattr(doc, "record_type", TYPE_SEPARATOR); |
461 | 599 | _setattr(doc, "position", bookmarksService.getItemIndex(item_id)); | ||
462 | 582 | break; | 600 | break; |
463 | 583 | default: | 601 | default: |
464 | 584 | Log.error("Can not handle item " + item_id + " of type " + | 602 | Log.error("Can not handle item " + item_id + " of type " + |
465 | 585 | 603 | ||
466 | === modified file 'mozmill/shared-modules/bookmarks.js' | |||
467 | --- mozmill/shared-modules/bookmarks.js 2011-02-15 09:33:35 +0000 | |||
468 | +++ mozmill/shared-modules/bookmarks.js 2011-03-04 13:02:54 +0000 | |||
469 | @@ -62,8 +62,15 @@ | |||
470 | 62 | } | 62 | } |
471 | 63 | } | 63 | } |
472 | 64 | 64 | ||
473 | 65 | function setGuid(item_id, guid) { | ||
474 | 66 | annotationService.setItemAnnotation( | ||
475 | 67 | item_id, GUID_ANNOTATION, guid, | ||
476 | 68 | 0, annotationService.EXPIRE_NEVER); | ||
477 | 69 | } | ||
478 | 70 | |||
479 | 65 | exports.bookmarksService = bookmarksService; | 71 | exports.bookmarksService = bookmarksService; |
480 | 66 | exports.livemarkService = livemarkService; | 72 | exports.livemarkService = livemarkService; |
481 | 67 | exports.annotationService = annotationService; | 73 | exports.annotationService = annotationService; |
482 | 68 | exports.createURI = createURI; | 74 | exports.createURI = createURI; |
483 | 69 | exports.clearBookmarks = clearBookmarks; | 75 | exports.clearBookmarks = clearBookmarks; |
484 | 76 | exports.setGuid = setGuid; | ||
485 | 70 | 77 | ||
486 | === added file 'mozmill/tests/test_migration.js' | |||
487 | --- mozmill/tests/test_migration.js 1970-01-01 00:00:00 +0000 | |||
488 | +++ mozmill/tests/test_migration.js 2011-03-04 13:02:54 +0000 | |||
489 | @@ -0,0 +1,425 @@ | |||
490 | 1 | var bm = require("../shared-modules/bookmarks"); | ||
491 | 2 | |||
492 | 3 | const TIMEOUT = 5000; | ||
493 | 4 | |||
494 | 5 | const RECORD_PREFIX = ( | ||
495 | 6 | "http://www.freedesktop.org/wiki/Specifications/desktopcouch/"); | ||
496 | 7 | const TYPE_BOOKMARK = RECORD_PREFIX + "bookmark"; | ||
497 | 8 | const TYPE_FOLDER = RECORD_PREFIX + "folder"; | ||
498 | 9 | const TYPE_FEED = RECORD_PREFIX + "feed"; | ||
499 | 10 | const TYPE_SEPARATOR = RECORD_PREFIX + "separator"; | ||
500 | 11 | |||
501 | 12 | |||
502 | 13 | var setupModule = function(module) { | ||
503 | 14 | module.controller = mozmill.getBrowserController(); | ||
504 | 15 | module.jum = {}; | ||
505 | 16 | module.desktopcouch = {}; | ||
506 | 17 | module.sync = {}; | ||
507 | 18 | module.migration = {}; | ||
508 | 19 | Cu.import("resource://mozmill/modules/jum.js", module.jum); | ||
509 | 20 | Cu.import("resource://bindwood/desktopcouch.jsm", module.desktopcouch); | ||
510 | 21 | Cu.import("resource://bindwood/sync.jsm", module.sync); | ||
511 | 22 | Cu.import("resource://bindwood/migration.jsm", module.migration); | ||
512 | 23 | module.couch = null; | ||
513 | 24 | module.synchroniser = null; | ||
514 | 25 | bm.clearBookmarks(); | ||
515 | 26 | }; | ||
516 | 27 | |||
517 | 28 | |||
518 | 29 | var setupTest = function(test) { | ||
519 | 30 | var done = false; | ||
520 | 31 | desktopcouch.connect_desktopcouch("test_bookmarks", function(db) { | ||
521 | 32 | couch = db; | ||
522 | 33 | done = true; | ||
523 | 34 | }, function (message) {}); | ||
524 | 35 | controller.waitFor( | ||
525 | 36 | function() { return done; }, "Could not connect to CouchDB", TIMEOUT); | ||
526 | 37 | jum.assertNotEquals(couch, null); | ||
527 | 38 | |||
528 | 39 | try { | ||
529 | 40 | couch.createDb(); | ||
530 | 41 | } catch (e) { | ||
531 | 42 | if (e.error != 'file_exists') | ||
532 | 43 | throw(e); | ||
533 | 44 | } | ||
534 | 45 | synchroniser = new sync.Synchroniser(couch, "profile_name"); | ||
535 | 46 | synchroniser.ensureCouchViews(); | ||
536 | 47 | }; | ||
537 | 48 | |||
538 | 49 | |||
539 | 50 | var teardownTest = function(test) { | ||
540 | 51 | synchroniser.uninit(); | ||
541 | 52 | couch.deleteDb(); | ||
542 | 53 | bm.clearBookmarks(); | ||
543 | 54 | }; | ||
544 | 55 | |||
545 | 56 | |||
546 | 57 | var test_get_schema_version = function() { | ||
547 | 58 | var sm = new migration.SchemaMigration(couch, 'profile_name'); | ||
548 | 59 | // With no root document, the database must be from 0.4.2. | ||
549 | 60 | jum.assertEquals(sm.get_schema_version(), 0); | ||
550 | 61 | |||
551 | 62 | // Create a 1.0.x style root document. | ||
552 | 63 | var root_doc = { | ||
553 | 64 | _id: 'root_profile_name', | ||
554 | 65 | children: ['old_toolbar', 'old_menu', 'old_unfiled'], | ||
555 | 66 | application_annotations: { | ||
556 | 67 | Firefox: { | ||
557 | 68 | profile: 'profile_name', | ||
558 | 69 | last_modified: 1 | ||
559 | 70 | } | ||
560 | 71 | } | ||
561 | 72 | }; | ||
562 | 73 | couch.save(root_doc); | ||
563 | 74 | jum.assertEquals(sm.get_schema_version(), 1); | ||
564 | 75 | |||
565 | 76 | // Now modify it to match this version. | ||
566 | 77 | root_doc.record_type = TYPE_FOLDER; | ||
567 | 78 | root_doc.record_type_version = 2; | ||
568 | 79 | root_doc.children = [ | ||
569 | 80 | 'toolbar_profile_name', 'menu_profile_name', 'unfiled_profile_name']; | ||
570 | 81 | couch.save(root_doc); | ||
571 | 82 | jum.assertEquals(sm.get_schema_version(), 2); | ||
572 | 83 | |||
573 | 84 | // Future schema versions will update record_type_version. | ||
574 | 85 | root_doc.record_type_version = 42; | ||
575 | 86 | couch.save(root_doc); | ||
576 | 87 | jum.assertEquals(sm.get_schema_version(), 42); | ||
577 | 88 | }; | ||
578 | 89 | |||
579 | 90 | |||
580 | 91 | // Build up bookmarks that match the sample data below. | ||
581 | 92 | var make_sample_bookmarks = function() { | ||
582 | 93 | var folder1_id = bm.bookmarksService.createFolder( | ||
583 | 94 | bm.bookmarksService.toolbarFolder, 'Folder 1', | ||
584 | 95 | bm.bookmarksService.DEFAULT_INDEX); | ||
585 | 96 | bm.setGuid(folder1_id, 'folder1'); | ||
586 | 97 | |||
587 | 98 | var livemark1_id = bm.livemarkService.createLivemark( | ||
588 | 99 | folder1_id, 'Livemark 1', | ||
589 | 100 | bm.createURI('http://www.example.com/'), | ||
590 | 101 | bm.createURI('http://www.example.com/feed'), | ||
591 | 102 | bm.bookmarksService.DEFAULT_INDEX); | ||
592 | 103 | bm.setGuid(livemark1_id, 'livemark1'); | ||
593 | 104 | |||
594 | 105 | var bookmark1_id = bm.bookmarksService.insertBookmark( | ||
595 | 106 | bm.bookmarksService.toolbarFolder, | ||
596 | 107 | bm.createURI('http://www.example.com/bookmark1'), | ||
597 | 108 | bm.bookmarksService.DEFAULT_INDEX, 'Bookmark 1'); | ||
598 | 109 | bm.setGuid(bookmark1_id, 'bookmark1'); | ||
599 | 110 | |||
600 | 111 | var bookmark2_id = bm.bookmarksService.insertBookmark( | ||
601 | 112 | bm.bookmarksService.bookmarksMenuFolder, | ||
602 | 113 | bm.createURI('http://www.example.com/bookmark2'), | ||
603 | 114 | bm.bookmarksService.DEFAULT_INDEX, 'Bookmark 2'); | ||
604 | 115 | bm.setGuid(bookmark2_id, 'bookmark2'); | ||
605 | 116 | |||
606 | 117 | var separator1_id = bm.bookmarksService.insertSeparator( | ||
607 | 118 | bm.bookmarksService.bookmarksMenuFolder, | ||
608 | 119 | bm.bookmarksService.DEFAULT_INDEX); | ||
609 | 120 | bm.setGuid(separator1_id, 'separator1'); | ||
610 | 121 | |||
611 | 122 | var bookmark3_id = bm.bookmarksService.insertBookmark( | ||
612 | 123 | bm.bookmarksService.unfiledBookmarksFolder, | ||
613 | 124 | bm.createURI('http://www.example.com/bookmark3'), | ||
614 | 125 | bm.bookmarksService.DEFAULT_INDEX, 'Bookmark 3'); | ||
615 | 126 | bm.setGuid(bookmark3_id, 'bookmark3'); | ||
616 | 127 | }; | ||
617 | 128 | |||
618 | 129 | |||
619 | 130 | // Make Version 0 (Bindwood 0.4.2) sample data | ||
620 | 131 | var make_sample_data_v0 = function() { | ||
621 | 132 | couch.bulkSave([ | ||
622 | 133 | { | ||
623 | 134 | _id: 'couchdb_folder1', | ||
624 | 135 | record_type: TYPE_FOLDER, | ||
625 | 136 | title: 'Folder 1', | ||
626 | 137 | application_annotations: { | ||
627 | 138 | uuid: 'folder1', | ||
628 | 139 | folder: 'toolbarFolder', | ||
629 | 140 | profile: 'profile_name' | ||
630 | 141 | } | ||
631 | 142 | }, | ||
632 | 143 | { | ||
633 | 144 | _id: 'couchdb_livemark1', | ||
634 | 145 | record_type: TYPE_FOLDER, | ||
635 | 146 | title: 'Livemark 1', | ||
636 | 147 | application_annotations: { | ||
637 | 148 | uuid: 'livemark1', | ||
638 | 149 | folder: 'Folder 1', | ||
639 | 150 | profile: 'profile_name' | ||
640 | 151 | } | ||
641 | 152 | }, | ||
642 | 153 | { | ||
643 | 154 | _id: 'couchdb_bookmark1', | ||
644 | 155 | record_type: TYPE_BOOKMARK, | ||
645 | 156 | title: 'Bookmark 1', | ||
646 | 157 | uri: 'http://www.example.com/bookmark1', | ||
647 | 158 | application_annotations: { | ||
648 | 159 | uuid: 'bookmark1', | ||
649 | 160 | folder: 'toolbarFolder', | ||
650 | 161 | profile: 'profile_name' | ||
651 | 162 | } | ||
652 | 163 | }, | ||
653 | 164 | { | ||
654 | 165 | _id: 'couchdb_bookmark2', | ||
655 | 166 | record_type: TYPE_BOOKMARK, | ||
656 | 167 | title: 'Bookmark 2', | ||
657 | 168 | uri: 'http://www.example.com/bookmark2', | ||
658 | 169 | application_annotations: { | ||
659 | 170 | uuid: 'bookmark2', | ||
660 | 171 | folder: 'bookmarksMenuFolder', | ||
661 | 172 | profile: 'profile_name' | ||
662 | 173 | } | ||
663 | 174 | }, | ||
664 | 175 | { | ||
665 | 176 | _id: 'couchdb_separator1', | ||
666 | 177 | record_type: TYPE_SEPARATOR, | ||
667 | 178 | title: null, | ||
668 | 179 | application_annotations: { | ||
669 | 180 | uuid: 'separator1', | ||
670 | 181 | folder: 'bookmarksMenuFolder', | ||
671 | 182 | profile: 'profile_name' | ||
672 | 183 | } | ||
673 | 184 | }, | ||
674 | 185 | { | ||
675 | 186 | _id: 'couchdb_bookmark3', | ||
676 | 187 | record_type: TYPE_BOOKMARK, | ||
677 | 188 | title: 'Bookmark 3', | ||
678 | 189 | uri: 'http://www.example.com/bookmark3', | ||
679 | 190 | application_annotations: { | ||
680 | 191 | uuid: 'bookmark3', | ||
681 | 192 | folder: 'unfiledBookmarksFolder', | ||
682 | 193 | profile: 'profile_name' | ||
683 | 194 | } | ||
684 | 195 | } | ||
685 | 196 | ]); | ||
686 | 197 | }; | ||
687 | 198 | |||
688 | 199 | |||
689 | 200 | // Make Version 1 (Bindwood 1.0.x) sample data | ||
690 | 201 | var make_sample_data_v1 = function() { | ||
691 | 202 | var common_annotations = { | ||
692 | 203 | Firefox: { | ||
693 | 204 | profile: 'profile_name', | ||
694 | 205 | last_modified: 1, | ||
695 | 206 | garbage: '' | ||
696 | 207 | } | ||
697 | 208 | }; | ||
698 | 209 | couch.bulkSave([ | ||
699 | 210 | { | ||
700 | 211 | _id: 'root_profile_name', | ||
701 | 212 | children: ['obsolete_toolbar', 'obsolete_menu', 'obsolete_unfiled'], | ||
702 | 213 | application_annotations: common_annotations | ||
703 | 214 | }, | ||
704 | 215 | { | ||
705 | 216 | _id: 'obsolete_toolbar', | ||
706 | 217 | record_type: TYPE_FOLDER, | ||
707 | 218 | record_type_version: 1, | ||
708 | 219 | title: 'Bookmarks Toolbar', | ||
709 | 220 | children: ['folder1', 'bookmark1'], | ||
710 | 221 | application_annotations: common_annotations | ||
711 | 222 | }, | ||
712 | 223 | { | ||
713 | 224 | _id: 'folder1', | ||
714 | 225 | record_type: TYPE_FOLDER, | ||
715 | 226 | record_type_version: 1, | ||
716 | 227 | title: 'Folder 1', | ||
717 | 228 | children: ['livemark1'], | ||
718 | 229 | application_annotations: common_annotations | ||
719 | 230 | }, | ||
720 | 231 | { | ||
721 | 232 | _id: 'livemark1', | ||
722 | 233 | record_type: TYPE_FEED, | ||
723 | 234 | record_type_version: 1, | ||
724 | 235 | title: 'Livemark 1', | ||
725 | 236 | feed_uri: 'http://www.example.com/feed', | ||
726 | 237 | site_uri: 'http://www.example.com/', | ||
727 | 238 | application_annotations: common_annotations | ||
728 | 239 | }, | ||
729 | 240 | { | ||
730 | 241 | _id: 'bookmark1', | ||
731 | 242 | record_type: TYPE_BOOKMARK, | ||
732 | 243 | record_type_version: 1, | ||
733 | 244 | title: 'Bookmark 1', | ||
734 | 245 | uri: 'http://www.example.com/bookmark1', | ||
735 | 246 | application_annotations: common_annotations | ||
736 | 247 | }, | ||
737 | 248 | { | ||
738 | 249 | _id: 'obsolete_menu', | ||
739 | 250 | record_type: TYPE_FOLDER, | ||
740 | 251 | record_type_version: 1, | ||
741 | 252 | title: 'Bookmarks Menu', | ||
742 | 253 | children: ['bookmark2', 'separator1'], | ||
743 | 254 | application_annotations: common_annotations | ||
744 | 255 | }, | ||
745 | 256 | { | ||
746 | 257 | _id: 'bookmark2', | ||
747 | 258 | record_type: TYPE_BOOKMARK, | ||
748 | 259 | record_type_version: 1, | ||
749 | 260 | title: 'Bookmark 2', | ||
750 | 261 | uri: 'http://www.example.com/bookmark2', | ||
751 | 262 | application_annotations: common_annotations | ||
752 | 263 | }, | ||
753 | 264 | { | ||
754 | 265 | _id: 'separator1', | ||
755 | 266 | record_type: TYPE_SEPARATOR, | ||
756 | 267 | record_type_version: 1, | ||
757 | 268 | application_annotations: common_annotations | ||
758 | 269 | }, | ||
759 | 270 | { | ||
760 | 271 | _id: 'obsolete_unfiled', | ||
761 | 272 | record_type: TYPE_FOLDER, | ||
762 | 273 | record_type_version: 1, | ||
763 | 274 | title: 'Unfiled Bookmarks', | ||
764 | 275 | children: ['bookmark3'], | ||
765 | 276 | application_annotations: common_annotations | ||
766 | 277 | }, | ||
767 | 278 | { | ||
768 | 279 | _id: 'bookmark3', | ||
769 | 280 | record_type: TYPE_BOOKMARK, | ||
770 | 281 | record_type_version: 1, | ||
771 | 282 | title: 'Bookmark 3', | ||
772 | 283 | uri: 'http://www.example.com/bookmark3', | ||
773 | 284 | application_annotations: common_annotations | ||
774 | 285 | }, | ||
775 | 286 | { | ||
776 | 287 | _id: 'orphaned_bookmark', | ||
777 | 288 | record_type: TYPE_BOOKMARK, | ||
778 | 289 | record_type_version: 1, | ||
779 | 290 | title: 'Orphaned Bookmark', | ||
780 | 291 | uri: 'http://www.example.com/orphan', | ||
781 | 292 | application_annotations: common_annotations | ||
782 | 293 | } | ||
783 | 294 | ]); | ||
784 | 295 | }; | ||
785 | 296 | |||
786 | 297 | // Verify that the database contains expected v2 sample data. | ||
787 | 298 | var verify_sample_data_v2 = function() { | ||
788 | 299 | var root = couch.open('root_profile_name'); | ||
789 | 300 | jum.assertNotNull(root); | ||
790 | 301 | jum.assertEquals(root.record_type, TYPE_FOLDER); | ||
791 | 302 | jum.assertEquals(root.record_type_version, 2); | ||
792 | 303 | jum.assertEquals(root.children.length, 3); | ||
793 | 304 | jum.assertEquals(root.children[0], 'toolbar_profile_name'); | ||
794 | 305 | jum.assertEquals(root.children[1], 'menu_profile_name'); | ||
795 | 306 | jum.assertEquals(root.children[2], 'unfiled_profile_name'); | ||
796 | 307 | |||
797 | 308 | var toolbar = couch.open('toolbar_profile_name'); | ||
798 | 309 | jum.assertNotNull(toolbar); | ||
799 | 310 | jum.assertEquals(toolbar.record_type, TYPE_FOLDER); | ||
800 | 311 | jum.assertEquals(toolbar.record_type_version, 2); | ||
801 | 312 | jum.assertEquals(toolbar.parent_guid, 'root_profile_name'); | ||
802 | 313 | jum.assertEquals(toolbar.children.length, 2); | ||
803 | 314 | jum.assertEquals(toolbar.children[0], 'folder1'); | ||
804 | 315 | jum.assertEquals(toolbar.children[1], 'bookmark1'); | ||
805 | 316 | |||
806 | 317 | var folder1 = couch.open('folder1'); | ||
807 | 318 | jum.assertNotNull(folder1); | ||
808 | 319 | jum.assertEquals(folder1.record_type, TYPE_FOLDER); | ||
809 | 320 | jum.assertEquals(folder1.record_type_version, 2); | ||
810 | 321 | jum.assertEquals(folder1.parent_guid, 'toolbar_profile_name'); | ||
811 | 322 | jum.assertEquals(folder1.title, 'Folder 1'); | ||
812 | 323 | jum.assertEquals(folder1.children.length, 1); | ||
813 | 324 | jum.assertEquals(folder1.children[0], 'livemark1'); | ||
814 | 325 | |||
815 | 326 | var livemark1 = couch.open('livemark1'); | ||
816 | 327 | jum.assertNotNull(livemark1); | ||
817 | 328 | jum.assertEquals(livemark1.record_type, TYPE_FEED); | ||
818 | 329 | jum.assertEquals(livemark1.record_type_version, 2); | ||
819 | 330 | jum.assertEquals(livemark1.parent_guid, 'folder1'); | ||
820 | 331 | jum.assertEquals(livemark1.title, 'Livemark 1'); | ||
821 | 332 | jum.assertEquals(livemark1.site_uri, 'http://www.example.com/') | ||
822 | 333 | jum.assertEquals(livemark1.feed_uri, 'http://www.example.com/feed') | ||
823 | 334 | |||
824 | 335 | var bookmark1 = couch.open('bookmark1'); | ||
825 | 336 | jum.assertNotNull(bookmark1); | ||
826 | 337 | jum.assertEquals(bookmark1.record_type, TYPE_BOOKMARK); | ||
827 | 338 | jum.assertEquals(bookmark1.record_type_version, 2); | ||
828 | 339 | jum.assertEquals(bookmark1.parent_guid, 'toolbar_profile_name'); | ||
829 | 340 | jum.assertEquals(bookmark1.title, 'Bookmark 1'); | ||
830 | 341 | jum.assertEquals(bookmark1.uri, 'http://www.example.com/bookmark1'); | ||
831 | 342 | |||
832 | 343 | var menu = couch.open('menu_profile_name'); | ||
833 | 344 | jum.assertNotNull(menu); | ||
834 | 345 | jum.assertEquals(menu.record_type, TYPE_FOLDER); | ||
835 | 346 | jum.assertEquals(menu.record_type_version, 2); | ||
836 | 347 | jum.assertEquals(menu.parent_guid, 'root_profile_name'); | ||
837 | 348 | jum.assertEquals(menu.children.length, 2); | ||
838 | 349 | jum.assertEquals(menu.children[0], 'bookmark2'); | ||
839 | 350 | jum.assertEquals(menu.children[1], 'separator1'); | ||
840 | 351 | |||
841 | 352 | var bookmark2 = couch.open('bookmark2'); | ||
842 | 353 | jum.assertNotNull(bookmark2); | ||
843 | 354 | jum.assertEquals(bookmark2.record_type, TYPE_BOOKMARK); | ||
844 | 355 | jum.assertEquals(bookmark2.record_type_version, 2); | ||
845 | 356 | jum.assertEquals(bookmark2.parent_guid, 'menu_profile_name'); | ||
846 | 357 | jum.assertEquals(bookmark2.title, 'Bookmark 2'); | ||
847 | 358 | jum.assertEquals(bookmark2.uri, 'http://www.example.com/bookmark2'); | ||
848 | 359 | |||
849 | 360 | var separator1 = couch.open('separator1'); | ||
850 | 361 | jum.assertNotNull(separator1); | ||
851 | 362 | jum.assertEquals(separator1.record_type, TYPE_SEPARATOR); | ||
852 | 363 | jum.assertEquals(separator1.record_type_version, 2); | ||
853 | 364 | jum.assertEquals(separator1.parent_guid, 'menu_profile_name'); | ||
854 | 365 | |||
855 | 366 | var unfiled = couch.open('unfiled_profile_name'); | ||
856 | 367 | jum.assertNotNull(unfiled); | ||
857 | 368 | jum.assertEquals(unfiled.record_type, TYPE_FOLDER); | ||
858 | 369 | jum.assertEquals(unfiled.record_type_version, 2); | ||
859 | 370 | jum.assertEquals(unfiled.parent_guid, 'root_profile_name'); | ||
860 | 371 | jum.assertEquals(unfiled.children.length, 1); | ||
861 | 372 | jum.assertEquals(unfiled.children[0], 'bookmark3'); | ||
862 | 373 | |||
863 | 374 | var bookmark3 = couch.open('bookmark3'); | ||
864 | 375 | jum.assertNotNull(bookmark3); | ||
865 | 376 | jum.assertEquals(bookmark3.record_type, TYPE_BOOKMARK); | ||
866 | 377 | jum.assertEquals(bookmark3.record_type_version, 2); | ||
867 | 378 | jum.assertEquals(bookmark3.parent_guid, 'unfiled_profile_name'); | ||
868 | 379 | jum.assertEquals(bookmark3.title, 'Bookmark 3'); | ||
869 | 380 | jum.assertEquals(bookmark3.uri, 'http://www.example.com/bookmark3'); | ||
870 | 381 | }; | ||
871 | 382 | |||
872 | 383 | |||
873 | 384 | var test_upgrade_1_to_2 = function() { | ||
874 | 385 | make_sample_data_v1(); | ||
875 | 386 | var sm = new migration.SchemaMigration(couch, 'profile_name'); | ||
876 | 387 | sm.upgrade_1_to_2(); | ||
877 | 388 | |||
878 | 389 | verify_sample_data_v2(); | ||
879 | 390 | |||
880 | 391 | // The old documents for the special folders have been removed. | ||
881 | 392 | jum.assertNull(couch.open('obsolete_toolbar')); | ||
882 | 393 | jum.assertNull(couch.open('obsolete_menu')); | ||
883 | 394 | jum.assertNull(couch.open('obsolete_unfiled')); | ||
884 | 395 | |||
885 | 396 | // Unneeded attributes removed from annotation. | ||
886 | 397 | var bookmark1_doc = couch.open('bookmark1'); | ||
887 | 398 | jum.assertUndefined(bookmark1_doc.application_annotations.Firefox.garbage); | ||
888 | 399 | |||
889 | 400 | // Orphaned items have been deleted. | ||
890 | 401 | jum.assertNull(couch.open('orphaned_bookmark')); | ||
891 | 402 | }; | ||
892 | 403 | |||
893 | 404 | |||
894 | 405 | var test_migrate_v0 = function() { | ||
895 | 406 | make_sample_bookmarks(); | ||
896 | 407 | make_sample_data_v0(); | ||
897 | 408 | |||
898 | 409 | synchroniser.last_seq = couch.info().last_seq; | ||
899 | 410 | synchroniser.init(); | ||
900 | 411 | synchroniser.sync(); | ||
901 | 412 | |||
902 | 413 | verify_sample_data_v2(); | ||
903 | 414 | }; | ||
904 | 415 | |||
905 | 416 | var test_migrate_v1 = function() { | ||
906 | 417 | make_sample_bookmarks(); | ||
907 | 418 | make_sample_data_v1(); | ||
908 | 419 | |||
909 | 420 | synchroniser.last_seq = couch.info().last_seq; | ||
910 | 421 | synchroniser.init(); | ||
911 | 422 | synchroniser.sync(); | ||
912 | 423 | |||
913 | 424 | verify_sample_data_v2(); | ||
914 | 425 | }; | ||
915 | 0 | 426 | ||
916 | === modified file 'mozmill/tests/test_sync_all.js' | |||
917 | --- mozmill/tests/test_sync_all.js 2011-03-04 13:02:54 +0000 | |||
918 | +++ mozmill/tests/test_sync_all.js 2011-03-04 13:02:54 +0000 | |||
919 | @@ -100,10 +100,23 @@ | |||
920 | 100 | }; | 100 | }; |
921 | 101 | 101 | ||
922 | 102 | var test_sync_remote = function() { | 102 | var test_sync_remote = function() { |
923 | 103 | couch.save({ | ||
924 | 104 | _id: 'root_profile_name', | ||
925 | 105 | record_type: 'http://www.freedesktop.org/wiki/Specifications/desktopcouch/folder', | ||
926 | 106 | record_type_version: 2, | ||
927 | 107 | children: [ | ||
928 | 108 | 'toolbar_profile_name', | ||
929 | 109 | 'menu_profile_name', | ||
930 | 110 | 'unfiled_profile_name' | ||
931 | 111 | ] | ||
932 | 112 | }); | ||
933 | 113 | |||
934 | 103 | var item_guid = '12345'; | 114 | var item_guid = '12345'; |
935 | 104 | var doc = { | 115 | var doc = { |
936 | 105 | _id: item_guid, | 116 | _id: item_guid, |
937 | 106 | record_type: 'http://www.freedesktop.org/wiki/Specifications/desktopcouch/bookmark', | 117 | record_type: 'http://www.freedesktop.org/wiki/Specifications/desktopcouch/bookmark', |
938 | 118 | record_type_version: 2, | ||
939 | 119 | parent_title: 'Bookmarks Toolbar', | ||
940 | 107 | parent_guid: 'toolbar_profile_name', | 120 | parent_guid: 'toolbar_profile_name', |
941 | 108 | title: 'Bookmark title', | 121 | title: 'Bookmark title', |
942 | 109 | uri: LOCAL_TEST_PAGE, | 122 | uri: LOCAL_TEST_PAGE, |
943 | @@ -173,6 +186,7 @@ | |||
944 | 173 | var doc = { | 186 | var doc = { |
945 | 174 | _id: item_guid, | 187 | _id: item_guid, |
946 | 175 | record_type: 'http://www.freedesktop.org/wiki/Specifications/desktopcouch/bookmark', | 188 | record_type: 'http://www.freedesktop.org/wiki/Specifications/desktopcouch/bookmark', |
947 | 189 | record_type_version: 2, | ||
948 | 176 | parent_guid: 'toolbar_profile_name', | 190 | parent_guid: 'toolbar_profile_name', |
949 | 177 | title: 'Bookmark title', | 191 | title: 'Bookmark title', |
950 | 178 | uri: LOCAL_TEST_PAGE, | 192 | uri: LOCAL_TEST_PAGE, |
951 | 179 | 193 | ||
952 | === modified file 'mozmill/tests/test_sync_from_couch.js' | |||
953 | --- mozmill/tests/test_sync_from_couch.js 2011-03-04 13:02:54 +0000 | |||
954 | +++ mozmill/tests/test_sync_from_couch.js 2011-03-04 13:02:54 +0000 | |||
955 | @@ -29,6 +29,7 @@ | |||
956 | 29 | synchroniser.processRecord({ | 29 | synchroniser.processRecord({ |
957 | 30 | _id: '12345', | 30 | _id: '12345', |
958 | 31 | record_type: 'http://www.freedesktop.org/wiki/Specifications/desktopcouch/bookmark', | 31 | record_type: 'http://www.freedesktop.org/wiki/Specifications/desktopcouch/bookmark', |
959 | 32 | record_type_version: 2, | ||
960 | 32 | parent_guid: 'toolbar_profile_name', | 33 | parent_guid: 'toolbar_profile_name', |
961 | 33 | title: 'Bookmark title', | 34 | title: 'Bookmark title', |
962 | 34 | uri: LOCAL_TEST_PAGE, | 35 | uri: LOCAL_TEST_PAGE, |
963 | @@ -54,6 +55,7 @@ | |||
964 | 54 | doc = { | 55 | doc = { |
965 | 55 | _id: '12345', | 56 | _id: '12345', |
966 | 56 | record_type: 'http://www.freedesktop.org/wiki/Specifications/desktopcouch/bookmark', | 57 | record_type: 'http://www.freedesktop.org/wiki/Specifications/desktopcouch/bookmark', |
967 | 58 | record_type_version: 2, | ||
968 | 57 | parent_guid: 'toolbar_profile_name', | 59 | parent_guid: 'toolbar_profile_name', |
969 | 58 | title: 'Bookmark title', | 60 | title: 'Bookmark title', |
970 | 59 | uri: LOCAL_TEST_PAGE, | 61 | uri: LOCAL_TEST_PAGE, |
971 | @@ -82,6 +84,7 @@ | |||
972 | 82 | synchroniser.processRecord({ | 84 | synchroniser.processRecord({ |
973 | 83 | _id: '12345', | 85 | _id: '12345', |
974 | 84 | record_type: 'http://www.freedesktop.org/wiki/Specifications/desktopcouch/folder', | 86 | record_type: 'http://www.freedesktop.org/wiki/Specifications/desktopcouch/folder', |
975 | 87 | record_type_version: 2, | ||
976 | 85 | parent_guid: 'toolbar_profile_name', | 88 | parent_guid: 'toolbar_profile_name', |
977 | 86 | title: 'Folder', | 89 | title: 'Folder', |
978 | 87 | children: [], | 90 | children: [], |
979 | @@ -107,6 +110,7 @@ | |||
980 | 107 | doc = { | 110 | doc = { |
981 | 108 | _id: '12345', | 111 | _id: '12345', |
982 | 109 | record_type: 'http://www.freedesktop.org/wiki/Specifications/desktopcouch/folder', | 112 | record_type: 'http://www.freedesktop.org/wiki/Specifications/desktopcouch/folder', |
983 | 113 | record_type_version: 2, | ||
984 | 110 | parent_guid: 'toolbar_profile_name', | 114 | parent_guid: 'toolbar_profile_name', |
985 | 111 | title: 'Folder', | 115 | title: 'Folder', |
986 | 112 | children: [], | 116 | children: [], |
987 | @@ -134,6 +138,7 @@ | |||
988 | 134 | synchroniser.processRecord({ | 138 | synchroniser.processRecord({ |
989 | 135 | _id: '12345', | 139 | _id: '12345', |
990 | 136 | record_type: 'http://www.freedesktop.org/wiki/Specifications/desktopcouch/feed', | 140 | record_type: 'http://www.freedesktop.org/wiki/Specifications/desktopcouch/feed', |
991 | 141 | record_type_version: 2, | ||
992 | 137 | parent_guid: 'toolbar_profile_name', | 142 | parent_guid: 'toolbar_profile_name', |
993 | 138 | title: 'Livemark', | 143 | title: 'Livemark', |
994 | 139 | site_uri: "http://www.example.com/", | 144 | site_uri: "http://www.example.com/", |
995 | @@ -161,6 +166,7 @@ | |||
996 | 161 | doc = { | 166 | doc = { |
997 | 162 | _id: '12345', | 167 | _id: '12345', |
998 | 163 | record_type: 'http://www.freedesktop.org/wiki/Specifications/desktopcouch/feed', | 168 | record_type: 'http://www.freedesktop.org/wiki/Specifications/desktopcouch/feed', |
999 | 169 | record_type_version: 2, | ||
1000 | 164 | parent_guid: 'toolbar_profile_name', | 170 | parent_guid: 'toolbar_profile_name', |
1001 | 165 | title: 'Livemark', | 171 | title: 'Livemark', |
1002 | 166 | site_uri: "http://www.example.com/", | 172 | site_uri: "http://www.example.com/", |
1003 | @@ -190,6 +196,7 @@ | |||
1004 | 190 | synchroniser.processRecord({ | 196 | synchroniser.processRecord({ |
1005 | 191 | _id: '12345', | 197 | _id: '12345', |
1006 | 192 | record_type: 'http://www.freedesktop.org/wiki/Specifications/desktopcouch/separator', | 198 | record_type: 'http://www.freedesktop.org/wiki/Specifications/desktopcouch/separator', |
1007 | 199 | record_type_version: 2, | ||
1008 | 193 | parent_guid: 'toolbar_profile_name', | 200 | parent_guid: 'toolbar_profile_name', |
1009 | 194 | application_annotations: { | 201 | application_annotations: { |
1010 | 195 | Firefox: { | 202 | Firefox: { |
1011 | @@ -209,6 +216,7 @@ | |||
1012 | 209 | doc = { | 216 | doc = { |
1013 | 210 | _id: '12345', | 217 | _id: '12345', |
1014 | 211 | record_type: 'http://www.freedesktop.org/wiki/Specifications/desktopcouch/separator', | 218 | record_type: 'http://www.freedesktop.org/wiki/Specifications/desktopcouch/separator', |
1015 | 219 | record_type_version: 2, | ||
1016 | 212 | parent_guid: 'toolbar_profile_name', | 220 | parent_guid: 'toolbar_profile_name', |
1017 | 213 | application_annotations: { | 221 | application_annotations: { |
1018 | 214 | Firefox: { | 222 | Firefox: { |
1019 | @@ -233,6 +241,7 @@ | |||
1020 | 233 | doc = { | 241 | doc = { |
1021 | 234 | _id: '12345', | 242 | _id: '12345', |
1022 | 235 | record_type: 'http://www.freedesktop.org/wiki/Specifications/desktopcouch/bookmark', | 243 | record_type: 'http://www.freedesktop.org/wiki/Specifications/desktopcouch/bookmark', |
1023 | 244 | record_type_version: 2, | ||
1024 | 236 | parent_guid: 'toolbar_profile_name', | 245 | parent_guid: 'toolbar_profile_name', |
1025 | 237 | title: 'Bookmark title', | 246 | title: 'Bookmark title', |
1026 | 238 | uri: LOCAL_TEST_PAGE, | 247 | uri: LOCAL_TEST_PAGE, |
1027 | @@ -262,6 +271,7 @@ | |||
1028 | 262 | synchroniser.processRecord({ | 271 | synchroniser.processRecord({ |
1029 | 263 | _id: '12345', | 272 | _id: '12345', |
1030 | 264 | record_type: 'http://www.freedesktop.org/wiki/Specifications/desktopcouch/folder', | 273 | record_type: 'http://www.freedesktop.org/wiki/Specifications/desktopcouch/folder', |
1031 | 274 | record_type_version: 2, | ||
1032 | 265 | parent_guid: 'toolbar_profile_name', | 275 | parent_guid: 'toolbar_profile_name', |
1033 | 266 | title: 'Folder', | 276 | title: 'Folder', |
1034 | 267 | children: ['67890'], | 277 | children: ['67890'], |
1035 | @@ -281,6 +291,7 @@ | |||
1036 | 281 | synchroniser.processRecord({ | 291 | synchroniser.processRecord({ |
1037 | 282 | _id: '67890', | 292 | _id: '67890', |
1038 | 283 | record_type: 'http://www.freedesktop.org/wiki/Specifications/desktopcouch/bookmark', | 293 | record_type: 'http://www.freedesktop.org/wiki/Specifications/desktopcouch/bookmark', |
1039 | 294 | record_type_version: 2, | ||
1040 | 284 | parent_guid: '12345', | 295 | parent_guid: '12345', |
1041 | 285 | title: 'Bookmark title', | 296 | title: 'Bookmark title', |
1042 | 286 | uri: LOCAL_TEST_PAGE, | 297 | uri: LOCAL_TEST_PAGE, |
1043 | @@ -300,6 +311,7 @@ | |||
1044 | 300 | synchroniser.processRecord({ | 311 | synchroniser.processRecord({ |
1045 | 301 | _id: '67890', | 312 | _id: '67890', |
1046 | 302 | record_type: 'http://www.freedesktop.org/wiki/Specifications/desktopcouch/bookmark', | 313 | record_type: 'http://www.freedesktop.org/wiki/Specifications/desktopcouch/bookmark', |
1047 | 314 | record_type_version: 2, | ||
1048 | 303 | parent_guid: '12345', | 315 | parent_guid: '12345', |
1049 | 304 | title: 'Bookmark title', | 316 | title: 'Bookmark title', |
1050 | 305 | uri: LOCAL_TEST_PAGE, | 317 | uri: LOCAL_TEST_PAGE, |
1051 | @@ -318,6 +330,7 @@ | |||
1052 | 318 | synchroniser.processRecord({ | 330 | synchroniser.processRecord({ |
1053 | 319 | _id: '12345', | 331 | _id: '12345', |
1054 | 320 | record_type: 'http://www.freedesktop.org/wiki/Specifications/desktopcouch/folder', | 332 | record_type: 'http://www.freedesktop.org/wiki/Specifications/desktopcouch/folder', |
1055 | 333 | record_type_version: 2, | ||
1056 | 321 | parent_guid: 'toolbar_profile_name', | 334 | parent_guid: 'toolbar_profile_name', |
1057 | 322 | title: 'Folder', | 335 | title: 'Folder', |
1058 | 323 | children: ['67890'], | 336 | children: ['67890'], |
1059 | @@ -342,6 +355,7 @@ | |||
1060 | 342 | synchroniser.processRecord({ | 355 | synchroniser.processRecord({ |
1061 | 343 | _id: 'parent', | 356 | _id: 'parent', |
1062 | 344 | record_type: 'http://www.freedesktop.org/wiki/Specifications/desktopcouch/folder', | 357 | record_type: 'http://www.freedesktop.org/wiki/Specifications/desktopcouch/folder', |
1063 | 358 | record_type_version: 2, | ||
1064 | 345 | parent_guid: 'toolbar_profile_name', | 359 | parent_guid: 'toolbar_profile_name', |
1065 | 346 | title: 'Folder', | 360 | title: 'Folder', |
1066 | 347 | children: ['child1', 'child2', 'child3', 'missing_child'], | 361 | children: ['child1', 'child2', 'child3', 'missing_child'], |
1067 | @@ -363,6 +377,7 @@ | |||
1068 | 363 | synchroniser.processRecord({ | 377 | synchroniser.processRecord({ |
1069 | 364 | _id: 'child1', | 378 | _id: 'child1', |
1070 | 365 | record_type: 'http://www.freedesktop.org/wiki/Specifications/desktopcouch/bookmark', | 379 | record_type: 'http://www.freedesktop.org/wiki/Specifications/desktopcouch/bookmark', |
1071 | 380 | record_type_version: 2, | ||
1072 | 366 | parent_guid: 'parent', | 381 | parent_guid: 'parent', |
1073 | 367 | title: 'Child 1', | 382 | title: 'Child 1', |
1074 | 368 | uri: LOCAL_TEST_PAGE + "#child1", | 383 | uri: LOCAL_TEST_PAGE + "#child1", |
1075 | @@ -376,6 +391,7 @@ | |||
1076 | 376 | synchroniser.processRecord({ | 391 | synchroniser.processRecord({ |
1077 | 377 | _id: 'child3', | 392 | _id: 'child3', |
1078 | 378 | record_type: 'http://www.freedesktop.org/wiki/Specifications/desktopcouch/bookmark', | 393 | record_type: 'http://www.freedesktop.org/wiki/Specifications/desktopcouch/bookmark', |
1079 | 394 | record_type_version: 2, | ||
1080 | 379 | parent_guid: 'parent', | 395 | parent_guid: 'parent', |
1081 | 380 | title: 'Child 3', | 396 | title: 'Child 3', |
1082 | 381 | uri: LOCAL_TEST_PAGE + "#child1", | 397 | uri: LOCAL_TEST_PAGE + "#child1", |
1083 | @@ -389,6 +405,7 @@ | |||
1084 | 389 | synchroniser.processRecord({ | 405 | synchroniser.processRecord({ |
1085 | 390 | _id: 'child2', | 406 | _id: 'child2', |
1086 | 391 | record_type: 'http://www.freedesktop.org/wiki/Specifications/desktopcouch/bookmark', | 407 | record_type: 'http://www.freedesktop.org/wiki/Specifications/desktopcouch/bookmark', |
1087 | 408 | record_type_version: 2, | ||
1088 | 392 | parent_guid: 'parent', | 409 | parent_guid: 'parent', |
1089 | 393 | title: 'Child 2', | 410 | title: 'Child 2', |
1090 | 394 | uri: LOCAL_TEST_PAGE + "#child1", | 411 | uri: LOCAL_TEST_PAGE + "#child1", |
1091 | 395 | 412 | ||
1092 | === modified file 'mozmill/tests/test_sync_to_couch.js' | |||
1093 | --- mozmill/tests/test_sync_to_couch.js 2011-03-04 13:02:54 +0000 | |||
1094 | +++ mozmill/tests/test_sync_to_couch.js 2011-03-04 13:02:54 +0000 | |||
1095 | @@ -56,6 +56,7 @@ | |||
1096 | 56 | var doc = couch.open(item_guid); | 56 | var doc = couch.open(item_guid); |
1097 | 57 | jum.assertEquals(doc.record_type, "http://www.freedesktop.org/wiki/" + | 57 | jum.assertEquals(doc.record_type, "http://www.freedesktop.org/wiki/" + |
1098 | 58 | "Specifications/desktopcouch/bookmark"); | 58 | "Specifications/desktopcouch/bookmark"); |
1099 | 59 | jum.assertEquals(doc.record_type_version, 2); | ||
1100 | 59 | jum.assertEquals(doc.application_annotations.Firefox.profile, | 60 | jum.assertEquals(doc.application_annotations.Firefox.profile, |
1101 | 60 | "profile_name"); | 61 | "profile_name"); |
1102 | 61 | jum.assertEquals(doc.parent_guid, "toolbar_profile_name"); | 62 | jum.assertEquals(doc.parent_guid, "toolbar_profile_name"); |
1103 | @@ -91,6 +92,7 @@ | |||
1104 | 91 | var doc = couch.open(folder_guid); | 92 | var doc = couch.open(folder_guid); |
1105 | 92 | jum.assertEquals(doc.record_type, "http://www.freedesktop.org/wiki/" + | 93 | jum.assertEquals(doc.record_type, "http://www.freedesktop.org/wiki/" + |
1106 | 93 | "Specifications/desktopcouch/folder"); | 94 | "Specifications/desktopcouch/folder"); |
1107 | 95 | jum.assertEquals(doc.record_type_version, 2); | ||
1108 | 94 | jum.assertEquals(doc.application_annotations.Firefox.profile, | 96 | jum.assertEquals(doc.application_annotations.Firefox.profile, |
1109 | 95 | "profile_name"); | 97 | "profile_name"); |
1110 | 96 | jum.assertEquals(doc.parent_guid, "toolbar_profile_name"); | 98 | jum.assertEquals(doc.parent_guid, "toolbar_profile_name"); |
1111 | @@ -128,6 +130,7 @@ | |||
1112 | 128 | var doc = couch.open(item_guid); | 130 | var doc = couch.open(item_guid); |
1113 | 129 | jum.assertEquals(doc.record_type, "http://www.freedesktop.org/wiki/" + | 131 | jum.assertEquals(doc.record_type, "http://www.freedesktop.org/wiki/" + |
1114 | 130 | "Specifications/desktopcouch/feed"); | 132 | "Specifications/desktopcouch/feed"); |
1115 | 133 | jum.assertEquals(doc.record_type_version, 2); | ||
1116 | 131 | jum.assertEquals(doc.application_annotations.Firefox.profile, | 134 | jum.assertEquals(doc.application_annotations.Firefox.profile, |
1117 | 132 | "profile_name"); | 135 | "profile_name"); |
1118 | 133 | jum.assertEquals(doc.parent_guid, "toolbar_profile_name"); | 136 | jum.assertEquals(doc.parent_guid, "toolbar_profile_name"); |
1119 | @@ -157,6 +160,7 @@ | |||
1120 | 157 | var doc = couch.open(item_guid); | 160 | var doc = couch.open(item_guid); |
1121 | 158 | jum.assertEquals(doc.record_type, "http://www.freedesktop.org/wiki/" + | 161 | jum.assertEquals(doc.record_type, "http://www.freedesktop.org/wiki/" + |
1122 | 159 | "Specifications/desktopcouch/separator"); | 162 | "Specifications/desktopcouch/separator"); |
1123 | 163 | jum.assertEquals(doc.record_type_version, 2); | ||
1124 | 160 | jum.assertEquals(doc.application_annotations.Firefox.profile, | 164 | jum.assertEquals(doc.application_annotations.Firefox.profile, |
1125 | 161 | "profile_name"); | 165 | "profile_name"); |
1126 | 162 | jum.assertEquals(doc.parent_guid, "toolbar_profile_name"); | 166 | jum.assertEquals(doc.parent_guid, "toolbar_profile_name"); |
1127 | @@ -191,6 +195,7 @@ | |||
1128 | 191 | var doc = couch.open(root_guid); | 195 | var doc = couch.open(root_guid); |
1129 | 192 | jum.assertEquals(doc.record_type, "http://www.freedesktop.org/wiki/" + | 196 | jum.assertEquals(doc.record_type, "http://www.freedesktop.org/wiki/" + |
1130 | 193 | "Specifications/desktopcouch/folder"); | 197 | "Specifications/desktopcouch/folder"); |
1131 | 198 | jum.assertEquals(doc.record_type_version, 2); | ||
1132 | 194 | jum.assertUndefined(doc.parent_guid); | 199 | jum.assertUndefined(doc.parent_guid); |
1133 | 195 | jum.assertEquals(doc.children.length, 3); | 200 | jum.assertEquals(doc.children.length, 3); |
1134 | 196 | jum.assertEquals(doc.children[0], synchroniser.guid_from_id( | 201 | jum.assertEquals(doc.children[0], synchroniser.guid_from_id( |
Looks good, tests pass.