Merge lp:~jamesh/bindwood/migration into lp:bindwood

Proposed by James Henstridge
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
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_type_version,
   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_type_version,
   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).

To post a comment you must log in.
Revision history for this message
Manuel de la Peña (mandel) :
review: Approve
Revision history for this message
Eric Casteleijn (thisfred) wrote :

Looks good, tests pass.

review: Approve
Revision history for this message
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

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'modules/bindwood.jsm'
--- modules/bindwood.jsm 2011-03-04 13:02:54 +0000
+++ modules/bindwood.jsm 2011-03-04 13:02:54 +0000
@@ -169,115 +169,4 @@
169 Log.exception("Problem setting up repeater.", e);169 Log.exception("Problem setting up repeater.", e);
170 }170 }
171 },171 },
172
173 migrateOlderBookmarkRecords: function() {
174 Log.debug(
175 "We're an older client. " +
176 "Let's migrate the remote records and re-sync.");
177
178 var additional = [];
179 var all_docs = Bindwood.couch.view("bookmarks/profile",
180 {
181 startkey: Bindwood.currentProfile,
182 endkey: Bindwood.currentProfile
183 });
184 var rows = all_docs.rows;
185
186 // Pull all records from Couch, and for each:
187
188 for (var i = 0; i < rows.length; i++) {
189 var row = rows[i];
190 Log.debug("Got a row: " + row);
191 var id = row.id;
192 Log.debug("Got an id: " + id);
193 var doc = Bindwood.couch.open(id);
194 Log.debug("Got a doc: " + doc);
195
196 if (doc.record_type_version >= 1) {
197 Log.debug(
198 "Record is already migrated Skipping...");
199 continue;
200 }
201
202 // get the uuid off the bookmark.
203 var old_uuid = doc.application_annotations.Firefox.uuid;
204 Log.debug(
205 "Got the old uuid from the record: " + old_uuid);
206 // look up itemId by uuid
207 // XXX: This probably needs to be made more robust
208 var itemId = Bindwood.itemIdForUUID(old_uuid);
209 Log.debug(
210 "Found its local itemID from the map: " + itemId);
211 // annotate the itemId with the document's _id
212 Bindwood.annotateItemWithUUID(itemId, id);
213 Log.debug(
214 "Annotating the item's uuid with the document's actual id");
215 // delete the uuid field off the record
216 delete doc.application_annotations.Firefox.uuid;
217 Log.debug("Deleted the document's uuid annotation");
218 // delete the folder field off the record
219 delete doc.application_annotations.Firefox.folder;
220 Log.debug("Deleted the document's folder annotation");
221
222 if (doc.deleted) {
223 Log.debug(
224 "The document was flagged as deleted, cleaning up.");
225 // swap .deleted for conventional .deleted
226 if (!doc.application_annotations) {
227 doc.application_annotations = {};
228 }
229 if (!doc.application_annotations['Ubuntu One']) {
230 doc.application_annotations['Ubuntu One'] = {};
231 }
232 if (!doc.application_annotations['Ubuntu One'].private_application_annotations) {
233 doc.application_annotations['Ubuntu One'].private_application_annotations = {};
234 }
235 doc.application_annotations['Ubuntu One'].private_application_annotations.deleted = true;
236 Log.debug(
237 "Moved deleted flag into private application annotations.");
238 delete doc.deleted;
239 Log.debug("Deleted the top-level .deleted flag.");
240 }
241
242 // update the document's record_type_version
243 doc.record_type_version = 1;
244 Log.debug("Set the schema version to 1");
245
246 // Ensure we're dealing with the proper record type on Migrate.
247 doc = Bindwood.decorateRecordByType(doc, itemId);
248
249 // add to additional
250 additional.push(doc);
251 Log.debug(
252 "Adding this doc to the stack of addition docs to push back.");
253 }
254
255 for (var i = 0; i < additional.length; i++) {
256 var doc = additional[i];
257 Log.debug(
258 "Preparing to push back " + doc.title || doc.record_type);
259 // Ensure that any remote folders have their .children
260 // populated, and in particular make sure that we've already
261 // modified their children's annotations/uuids
262 if (doc.record_type == Bindwood.TYPE_FOLDER) {
263 // XXX: This probably needs to be made more robust
264 var itemId = Bindwood.itemIdForUUID(doc._id);
265 doc.children = Bindwood.getUUIDsFromFolder(itemId);
266 Log.debug(
267 "Folder needed updating, calculated children: " +
268 doc.children);
269 }
270
271 try {
272 var response = Bindwood.couch.save(doc);
273 // We can avoid having to process this revision when we
274 // pull it later
275 Bindwood.seen_revisions[response.rev] = true;
276 } catch(e) {
277 Log.exception(
278 "Problem saving record to CouchDB; record is " +
279 JSON.stringify(doc + ": ", e));
280 }
281 }
282 },
283};172};
284173
=== modified file 'modules/couch.jsm'
--- modules/couch.jsm 2011-02-04 06:03:15 +0000
+++ modules/couch.jsm 2011-03-04 13:02:54 +0000
@@ -100,7 +100,7 @@
100 if (docs[i]._id == undefined)100 if (docs[i]._id == undefined)
101 newCount++;101 newCount++;
102 }102 }
103 var newUuids = CouchDB.newUuids(docs.length);103 var newUuids = CouchDB.newUuids(newCount);
104 var newCount = 0;104 var newCount = 0;
105 for (var i=0; i<docs.length; i++) {105 for (var i=0; i<docs.length; i++) {
106 if (docs[i]._id == undefined)106 if (docs[i]._id == undefined)
@@ -112,6 +112,7 @@
112 json[option] = options[option];112 json[option] = options[option];
113 }113 }
114 this.last_req = this.request("POST", this.uri + "_bulk_docs", {114 this.last_req = this.request("POST", this.uri + "_bulk_docs", {
115 headers: {"Content-Type": "application/json"},
115 body: JSON.stringify(json)116 body: JSON.stringify(json)
116 });117 });
117 if (this.last_req.status == 417) {118 if (this.last_req.status == 417) {
118119
=== added file 'modules/migration.jsm'
--- modules/migration.jsm 1970-01-01 00:00:00 +0000
+++ modules/migration.jsm 2011-03-04 13:02:54 +0000
@@ -0,0 +1,248 @@
1/*
2 * Copyright 2009-2011 Canonical Ltd.
3 *
4 * This program is free software: you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License version 3, as published
6 * by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranties of
10 * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
11 * PURPOSE. See the GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License along
14 * with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17const EXPORTED_SYMBOLS = ['SchemaMigration'];
18
19const Cu = Components.utils;
20
21Cu.import("resource://bindwood/logging.jsm");
22
23
24function SchemaMigration(couch, profile) {
25 this.couch = couch;
26 this.profile = profile;
27}
28
29SchemaMigration.prototype = {
30
31 get_schema_version: function() {
32 var doc = this.couch.open('root_' + this.profile);
33
34 if (!doc) {
35 // If there is no root document, we're dealing with the
36 // original Bindwood datbase schema.
37 return 0;
38 }
39 // If the root document does not have a record_type_version,
40 // assume it is the second schema version.
41 if (!doc.record_type_version) {
42 return 1;
43 }
44 // Otherwise, use the value of record_type_version.
45 return doc.record_type_version;
46 },
47
48 upgrade: function() {
49 var schema_version = this.get_schema_version();
50 Log.debug("Current schema version is " + schema_version);
51 switch (schema_version) {
52 case 0:
53 // Haven't written migration code for this format, so just
54 // wipe out the bookmarks and assume that we can rebuild
55 // from the local places database.
56 this.wipe_bookmarks();
57 return true;
58 case 1:
59 this.upgrade_1_to_2();
60 return true;
61 case 2:
62 // Nothing to be done: we're at the most recent version.
63 return false;
64 default:
65 Log.error("Unknown schema version " + schema_version);
66 return false;
67 }
68 },
69
70 wipe_bookmarks: function() {
71 Log.debug("Wiping all bookmarks for profile " + this.profile);
72 var result = this.couch.view("bindwood/bookmarks", {
73 key: this.profile,
74 include_docs: true,
75 });
76 var changes = [];
77 for each (var row in result.rows) {
78 var doc = row.doc;
79 changes.push({
80 _id: doc._id,
81 _rev: doc._rev,
82 _deleted: true
83 });
84 }
85 // Delete all the bookmarks.
86 this.couch.bulkSave(changes);
87 },
88
89 /* The format used by Bindwood 0.4.2. Bookmarks were represented as:
90 *
91 * {
92 * _id: '...',
93 * record_type: 'http://www.freedesktop.org/wiki/Specifications/desktopcouch/bookmark',
94 * title: 'Bookmark title',
95 * uri: 'http://www.example.com/',
96 * application_annotations: {
97 * Firefox: {
98 * uuid: '...', // This is the UUID associated with the local item.
99 * folder: 'Title of parent folder',
100 * profile: 'profile name'
101 * }
102 * }
103 * }
104 *
105 * Folders and separators had the appropriate record types, and
106 * had no URI property. Folder child ordering is not stored
107 * anywhere.
108 *
109 * There is no special handling of livemarks. They are stored as
110 * folders, and their children are also stored.
111 *
112 * The special parent names "toolbarFolder", "bookmarksMenuFolder"
113 * and "unfiledBookmarksFolder" were used to represent items at
114 * the top levels of each folder hierarchy.
115 */
116
117 /* The format used by Bindwood 1.0.x. Bookmarks look like this:
118 *
119 * {
120 * _id: '...', // This is the UUID associated with the local item.
121 * record_type: 'http://www.freedesktop.org/wiki/Specifications/desktopcouch/bookmark',
122 * record_type_version: 1,
123 * title: 'Bookmark title',
124 * uri: 'http://www.example.com/',
125 * application_annotations: {
126 * Firefox: {
127 * profile: 'profile name'
128 * last_modified: ..., // time in microseconds since epoch
129 * }
130 * }
131 * }
132 *
133 * Folders contain a list of the IDs of their children (the
134 * opposite of the 0.4.2 format), which also acts as a way to
135 * store the child ordering.
136 *
137 * Livemarks are stored with their own record type. They look
138 * similar to normal bookmarks, but store site_uri and feed_uri
139 * instead of a single bookmark URI.
140 */
141 upgrade_1_to_2: function() {
142 Log.debug("Upgrading bookmarks for profile " + this.profile +
143 " from schema v1 to v2");
144 var result = this.couch.view("bindwood/bookmarks", {
145 key: this.profile,
146 include_docs: true,
147 });
148
149 var changes = [];
150
151 // Build a map of document IDs to the documents they reflect.
152 var docs_by_id = {};
153 for each (var row in result.rows) {
154 docs_by_id[row.id] = row.doc;
155 }
156
157 // Fix up children of the root document. The children (which
158 // represent the toolbar, bookmarks menu and unfiled bookmarks
159 // folders) should be renamed to fixed identifiers.
160 var root_doc = docs_by_id['root_' + this.profile];
161 root_doc.record_type = 'http://www.freedesktop.org/wiki/Specifications/desktopcouch/folder';
162 var expected_children = [
163 'toolbar_' + this.profile,
164 'menu_' + this.profile,
165 'unfiled_' + this.profile];
166 for (var i = 0; i < expected_children.length; i++) {
167 var old_id = root_doc.children[i];
168 var new_id = expected_children[i];
169 // Existing document has expected name.
170 if (old_id == new_id) {
171 continue;
172 }
173 var doc = docs_by_id[old_id];
174 delete docs_by_id[old_id];
175
176 // Schedule deletion of old document
177 changes.push({
178 _id: doc._id,
179 _rev: doc._rev,
180 _deleted: true
181 });
182 doc._id = new_id;
183 delete doc._rev;
184 docs_by_id[new_id] = doc;
185 root_doc.children[i] = new_id;
186 }
187
188 // Walk the bookmarks tree from the root node to determine
189 // which documents are reachable, and build up a parent map.
190 var reachable = {};
191 var parents_by_id = {};
192
193 var remaining = [root_doc];
194 reachable[root_doc._id] = true;
195 while (remaining.length > 0) {
196 var doc = remaining.pop();
197 for each (var child_id in doc.children) {
198 parents_by_id[child_id] = doc;
199 reachable[child_id] = true;
200
201 var child_doc = docs_by_id[child_id];
202 if (child_doc && child_doc.record_type == 'http://www.freedesktop.org/wiki/Specifications/desktopcouch/folder') {
203 remaining.push(child_doc);
204 }
205 }
206 }
207
208 // Now update the documents.
209 for each (var doc in docs_by_id) {
210 // If the document can not be reached from the root, then
211 // it does not belong in the document tree.
212 if (!reachable[doc._id]) {
213 Log.debug("Deleting bookmark " + doc._id +
214 " is not reachable from root.");
215 changes.push({
216 _id: doc._id,
217 _rev: doc._rev,
218 _deleted: true
219 });
220 continue;
221 }
222
223 doc.record_type_version = 2;
224 var parent_doc = parents_by_id[doc._id]
225 if (parent_doc) {
226 doc.parent_guid = parent_doc._id;
227 doc.parent_title = parent_doc.title;
228 }
229
230 // Bindwood 1.0.x would store a lot of useless data in the
231 // Firefox section of the document (basically anything
232 // that triggered an onItemChanged callback). Keep only
233 // the information we care about.
234 var old_annotations = doc.application_annotations.Firefox;
235 var new_annotations = {
236 profile: old_annotations.profile,
237 last_modified: old_annotations.last_modified
238 };
239 doc.application_annotations.Firefox = new_annotations;
240
241 changes.push(doc);
242 }
243 // Now push the updates back to CouchDB.
244 Log.debug("Saving modifications to database.");
245 this.couch.bulkSave(changes);
246 Log.debug("Done.");
247 }
248};
0249
=== modified file 'modules/sync.jsm'
--- modules/sync.jsm 2011-03-04 13:02:54 +0000
+++ modules/sync.jsm 2011-03-04 13:02:54 +0000
@@ -22,6 +22,7 @@
22const Cu = Components.utils;22const Cu = Components.utils;
2323
24Cu.import("resource://bindwood/logging.jsm");24Cu.import("resource://bindwood/logging.jsm");
25Cu.import("resource://bindwood/migration.jsm");
2526
26const GUID_ANNOTATION = "bindwood/uuid";27const GUID_ANNOTATION = "bindwood/uuid";
27const PARENT_ANNOTATION = "bindwood/parent";28const PARENT_ANNOTATION = "bindwood/parent";
@@ -33,6 +34,8 @@
33const TYPE_FEED = RECORD_PREFIX + "feed";34const TYPE_FEED = RECORD_PREFIX + "feed";
34const TYPE_SEPARATOR = RECORD_PREFIX + "separator";35const TYPE_SEPARATOR = RECORD_PREFIX + "separator";
3536
37const RECORD_TYPE_VERSION = 2;
38
36var bookmarksService = Cc["@mozilla.org/browser/nav-bookmarks-service;1"]39var bookmarksService = Cc["@mozilla.org/browser/nav-bookmarks-service;1"]
37 .getService(Ci.nsINavBookmarksService);40 .getService(Ci.nsINavBookmarksService);
38var livemarkService = Cc["@mozilla.org/browser/livemark-service;2"]41var livemarkService = Cc["@mozilla.org/browser/livemark-service;2"]
@@ -62,6 +65,7 @@
62 Log.debug("Initialising synchroniser.");65 Log.debug("Initialising synchroniser.");
63 this.ensureDatabase();66 this.ensureDatabase();
64 this.ensureCouchViews();67 this.ensureCouchViews();
68 this.maybeMigrateData();
65 this.first_push = true;69 this.first_push = true;
66 this.observer = new BookmarksObserver(this);70 this.observer = new BookmarksObserver(this);
67 bookmarksService.addObserver(this.observer, false);71 bookmarksService.addObserver(this.observer, false);
@@ -132,6 +136,16 @@
132 }136 }
133 },137 },
134138
139 maybeMigrateData: function() {
140 migration = new SchemaMigration(this.couch, this.profile);
141
142 if (migration.upgrade()) {
143 Log.debug("Schema was upgraded, so resetting last known " +
144 "sequence number.");
145 this.last_seq = 0;
146 }
147 },
148
135 set_guid: function(item_id, guid) {149 set_guid: function(item_id, guid) {
136 // If the item has already been annotated with a GUID, clear150 // If the item has already been annotated with a GUID, clear
137 // the old GUID mapping from our cache.151 // the old GUID mapping from our cache.
@@ -543,6 +557,7 @@
543 }557 }
544 }558 }
545559
560 _setattr(doc, "record_type_version", RECORD_TYPE_VERSION);
546 if (!doc.application_annotations)561 if (!doc.application_annotations)
547 doc.application_annotations = {};562 doc.application_annotations = {};
548 if (!doc.application_annotations.Firefox)563 if (!doc.application_annotations.Firefox)
@@ -553,6 +568,8 @@
553 if (parent_id > 0) {568 if (parent_id > 0) {
554 var parent_guid = this.guid_from_id(parent_id);569 var parent_guid = this.guid_from_id(parent_id);
555 _setattr(doc, "parent_guid", parent_guid);570 _setattr(doc, "parent_guid", parent_guid);
571 _setattr(
572 doc, "parent_title", bookmarksService.getItemTitle(parent_id));
556 }573 }
557 switch (item_type) {574 switch (item_type) {
558 case bookmarksService.TYPE_BOOKMARK:575 case bookmarksService.TYPE_BOOKMARK:
@@ -579,6 +596,7 @@
579 break;596 break;
580 case bookmarksService.TYPE_SEPARATOR:597 case bookmarksService.TYPE_SEPARATOR:
581 _setattr(doc, "record_type", TYPE_SEPARATOR);598 _setattr(doc, "record_type", TYPE_SEPARATOR);
599 _setattr(doc, "position", bookmarksService.getItemIndex(item_id));
582 break;600 break;
583 default:601 default:
584 Log.error("Can not handle item " + item_id + " of type " +602 Log.error("Can not handle item " + item_id + " of type " +
585603
=== modified file 'mozmill/shared-modules/bookmarks.js'
--- mozmill/shared-modules/bookmarks.js 2011-02-15 09:33:35 +0000
+++ mozmill/shared-modules/bookmarks.js 2011-03-04 13:02:54 +0000
@@ -62,8 +62,15 @@
62 }62 }
63}63}
6464
65function setGuid(item_id, guid) {
66 annotationService.setItemAnnotation(
67 item_id, GUID_ANNOTATION, guid,
68 0, annotationService.EXPIRE_NEVER);
69}
70
65exports.bookmarksService = bookmarksService;71exports.bookmarksService = bookmarksService;
66exports.livemarkService = livemarkService;72exports.livemarkService = livemarkService;
67exports.annotationService = annotationService;73exports.annotationService = annotationService;
68exports.createURI = createURI;74exports.createURI = createURI;
69exports.clearBookmarks = clearBookmarks;75exports.clearBookmarks = clearBookmarks;
76exports.setGuid = setGuid;
7077
=== added file 'mozmill/tests/test_migration.js'
--- mozmill/tests/test_migration.js 1970-01-01 00:00:00 +0000
+++ mozmill/tests/test_migration.js 2011-03-04 13:02:54 +0000
@@ -0,0 +1,425 @@
1var bm = require("../shared-modules/bookmarks");
2
3const TIMEOUT = 5000;
4
5const RECORD_PREFIX = (
6 "http://www.freedesktop.org/wiki/Specifications/desktopcouch/");
7const TYPE_BOOKMARK = RECORD_PREFIX + "bookmark";
8const TYPE_FOLDER = RECORD_PREFIX + "folder";
9const TYPE_FEED = RECORD_PREFIX + "feed";
10const TYPE_SEPARATOR = RECORD_PREFIX + "separator";
11
12
13var setupModule = function(module) {
14 module.controller = mozmill.getBrowserController();
15 module.jum = {};
16 module.desktopcouch = {};
17 module.sync = {};
18 module.migration = {};
19 Cu.import("resource://mozmill/modules/jum.js", module.jum);
20 Cu.import("resource://bindwood/desktopcouch.jsm", module.desktopcouch);
21 Cu.import("resource://bindwood/sync.jsm", module.sync);
22 Cu.import("resource://bindwood/migration.jsm", module.migration);
23 module.couch = null;
24 module.synchroniser = null;
25 bm.clearBookmarks();
26};
27
28
29var setupTest = function(test) {
30 var done = false;
31 desktopcouch.connect_desktopcouch("test_bookmarks", function(db) {
32 couch = db;
33 done = true;
34 }, function (message) {});
35 controller.waitFor(
36 function() { return done; }, "Could not connect to CouchDB", TIMEOUT);
37 jum.assertNotEquals(couch, null);
38
39 try {
40 couch.createDb();
41 } catch (e) {
42 if (e.error != 'file_exists')
43 throw(e);
44 }
45 synchroniser = new sync.Synchroniser(couch, "profile_name");
46 synchroniser.ensureCouchViews();
47};
48
49
50var teardownTest = function(test) {
51 synchroniser.uninit();
52 couch.deleteDb();
53 bm.clearBookmarks();
54};
55
56
57var test_get_schema_version = function() {
58 var sm = new migration.SchemaMigration(couch, 'profile_name');
59 // With no root document, the database must be from 0.4.2.
60 jum.assertEquals(sm.get_schema_version(), 0);
61
62 // Create a 1.0.x style root document.
63 var root_doc = {
64 _id: 'root_profile_name',
65 children: ['old_toolbar', 'old_menu', 'old_unfiled'],
66 application_annotations: {
67 Firefox: {
68 profile: 'profile_name',
69 last_modified: 1
70 }
71 }
72 };
73 couch.save(root_doc);
74 jum.assertEquals(sm.get_schema_version(), 1);
75
76 // Now modify it to match this version.
77 root_doc.record_type = TYPE_FOLDER;
78 root_doc.record_type_version = 2;
79 root_doc.children = [
80 'toolbar_profile_name', 'menu_profile_name', 'unfiled_profile_name'];
81 couch.save(root_doc);
82 jum.assertEquals(sm.get_schema_version(), 2);
83
84 // Future schema versions will update record_type_version.
85 root_doc.record_type_version = 42;
86 couch.save(root_doc);
87 jum.assertEquals(sm.get_schema_version(), 42);
88};
89
90
91// Build up bookmarks that match the sample data below.
92var make_sample_bookmarks = function() {
93 var folder1_id = bm.bookmarksService.createFolder(
94 bm.bookmarksService.toolbarFolder, 'Folder 1',
95 bm.bookmarksService.DEFAULT_INDEX);
96 bm.setGuid(folder1_id, 'folder1');
97
98 var livemark1_id = bm.livemarkService.createLivemark(
99 folder1_id, 'Livemark 1',
100 bm.createURI('http://www.example.com/'),
101 bm.createURI('http://www.example.com/feed'),
102 bm.bookmarksService.DEFAULT_INDEX);
103 bm.setGuid(livemark1_id, 'livemark1');
104
105 var bookmark1_id = bm.bookmarksService.insertBookmark(
106 bm.bookmarksService.toolbarFolder,
107 bm.createURI('http://www.example.com/bookmark1'),
108 bm.bookmarksService.DEFAULT_INDEX, 'Bookmark 1');
109 bm.setGuid(bookmark1_id, 'bookmark1');
110
111 var bookmark2_id = bm.bookmarksService.insertBookmark(
112 bm.bookmarksService.bookmarksMenuFolder,
113 bm.createURI('http://www.example.com/bookmark2'),
114 bm.bookmarksService.DEFAULT_INDEX, 'Bookmark 2');
115 bm.setGuid(bookmark2_id, 'bookmark2');
116
117 var separator1_id = bm.bookmarksService.insertSeparator(
118 bm.bookmarksService.bookmarksMenuFolder,
119 bm.bookmarksService.DEFAULT_INDEX);
120 bm.setGuid(separator1_id, 'separator1');
121
122 var bookmark3_id = bm.bookmarksService.insertBookmark(
123 bm.bookmarksService.unfiledBookmarksFolder,
124 bm.createURI('http://www.example.com/bookmark3'),
125 bm.bookmarksService.DEFAULT_INDEX, 'Bookmark 3');
126 bm.setGuid(bookmark3_id, 'bookmark3');
127};
128
129
130// Make Version 0 (Bindwood 0.4.2) sample data
131var make_sample_data_v0 = function() {
132 couch.bulkSave([
133 {
134 _id: 'couchdb_folder1',
135 record_type: TYPE_FOLDER,
136 title: 'Folder 1',
137 application_annotations: {
138 uuid: 'folder1',
139 folder: 'toolbarFolder',
140 profile: 'profile_name'
141 }
142 },
143 {
144 _id: 'couchdb_livemark1',
145 record_type: TYPE_FOLDER,
146 title: 'Livemark 1',
147 application_annotations: {
148 uuid: 'livemark1',
149 folder: 'Folder 1',
150 profile: 'profile_name'
151 }
152 },
153 {
154 _id: 'couchdb_bookmark1',
155 record_type: TYPE_BOOKMARK,
156 title: 'Bookmark 1',
157 uri: 'http://www.example.com/bookmark1',
158 application_annotations: {
159 uuid: 'bookmark1',
160 folder: 'toolbarFolder',
161 profile: 'profile_name'
162 }
163 },
164 {
165 _id: 'couchdb_bookmark2',
166 record_type: TYPE_BOOKMARK,
167 title: 'Bookmark 2',
168 uri: 'http://www.example.com/bookmark2',
169 application_annotations: {
170 uuid: 'bookmark2',
171 folder: 'bookmarksMenuFolder',
172 profile: 'profile_name'
173 }
174 },
175 {
176 _id: 'couchdb_separator1',
177 record_type: TYPE_SEPARATOR,
178 title: null,
179 application_annotations: {
180 uuid: 'separator1',
181 folder: 'bookmarksMenuFolder',
182 profile: 'profile_name'
183 }
184 },
185 {
186 _id: 'couchdb_bookmark3',
187 record_type: TYPE_BOOKMARK,
188 title: 'Bookmark 3',
189 uri: 'http://www.example.com/bookmark3',
190 application_annotations: {
191 uuid: 'bookmark3',
192 folder: 'unfiledBookmarksFolder',
193 profile: 'profile_name'
194 }
195 }
196 ]);
197};
198
199
200// Make Version 1 (Bindwood 1.0.x) sample data
201var make_sample_data_v1 = function() {
202 var common_annotations = {
203 Firefox: {
204 profile: 'profile_name',
205 last_modified: 1,
206 garbage: ''
207 }
208 };
209 couch.bulkSave([
210 {
211 _id: 'root_profile_name',
212 children: ['obsolete_toolbar', 'obsolete_menu', 'obsolete_unfiled'],
213 application_annotations: common_annotations
214 },
215 {
216 _id: 'obsolete_toolbar',
217 record_type: TYPE_FOLDER,
218 record_type_version: 1,
219 title: 'Bookmarks Toolbar',
220 children: ['folder1', 'bookmark1'],
221 application_annotations: common_annotations
222 },
223 {
224 _id: 'folder1',
225 record_type: TYPE_FOLDER,
226 record_type_version: 1,
227 title: 'Folder 1',
228 children: ['livemark1'],
229 application_annotations: common_annotations
230 },
231 {
232 _id: 'livemark1',
233 record_type: TYPE_FEED,
234 record_type_version: 1,
235 title: 'Livemark 1',
236 feed_uri: 'http://www.example.com/feed',
237 site_uri: 'http://www.example.com/',
238 application_annotations: common_annotations
239 },
240 {
241 _id: 'bookmark1',
242 record_type: TYPE_BOOKMARK,
243 record_type_version: 1,
244 title: 'Bookmark 1',
245 uri: 'http://www.example.com/bookmark1',
246 application_annotations: common_annotations
247 },
248 {
249 _id: 'obsolete_menu',
250 record_type: TYPE_FOLDER,
251 record_type_version: 1,
252 title: 'Bookmarks Menu',
253 children: ['bookmark2', 'separator1'],
254 application_annotations: common_annotations
255 },
256 {
257 _id: 'bookmark2',
258 record_type: TYPE_BOOKMARK,
259 record_type_version: 1,
260 title: 'Bookmark 2',
261 uri: 'http://www.example.com/bookmark2',
262 application_annotations: common_annotations
263 },
264 {
265 _id: 'separator1',
266 record_type: TYPE_SEPARATOR,
267 record_type_version: 1,
268 application_annotations: common_annotations
269 },
270 {
271 _id: 'obsolete_unfiled',
272 record_type: TYPE_FOLDER,
273 record_type_version: 1,
274 title: 'Unfiled Bookmarks',
275 children: ['bookmark3'],
276 application_annotations: common_annotations
277 },
278 {
279 _id: 'bookmark3',
280 record_type: TYPE_BOOKMARK,
281 record_type_version: 1,
282 title: 'Bookmark 3',
283 uri: 'http://www.example.com/bookmark3',
284 application_annotations: common_annotations
285 },
286 {
287 _id: 'orphaned_bookmark',
288 record_type: TYPE_BOOKMARK,
289 record_type_version: 1,
290 title: 'Orphaned Bookmark',
291 uri: 'http://www.example.com/orphan',
292 application_annotations: common_annotations
293 }
294 ]);
295};
296
297// Verify that the database contains expected v2 sample data.
298var verify_sample_data_v2 = function() {
299 var root = couch.open('root_profile_name');
300 jum.assertNotNull(root);
301 jum.assertEquals(root.record_type, TYPE_FOLDER);
302 jum.assertEquals(root.record_type_version, 2);
303 jum.assertEquals(root.children.length, 3);
304 jum.assertEquals(root.children[0], 'toolbar_profile_name');
305 jum.assertEquals(root.children[1], 'menu_profile_name');
306 jum.assertEquals(root.children[2], 'unfiled_profile_name');
307
308 var toolbar = couch.open('toolbar_profile_name');
309 jum.assertNotNull(toolbar);
310 jum.assertEquals(toolbar.record_type, TYPE_FOLDER);
311 jum.assertEquals(toolbar.record_type_version, 2);
312 jum.assertEquals(toolbar.parent_guid, 'root_profile_name');
313 jum.assertEquals(toolbar.children.length, 2);
314 jum.assertEquals(toolbar.children[0], 'folder1');
315 jum.assertEquals(toolbar.children[1], 'bookmark1');
316
317 var folder1 = couch.open('folder1');
318 jum.assertNotNull(folder1);
319 jum.assertEquals(folder1.record_type, TYPE_FOLDER);
320 jum.assertEquals(folder1.record_type_version, 2);
321 jum.assertEquals(folder1.parent_guid, 'toolbar_profile_name');
322 jum.assertEquals(folder1.title, 'Folder 1');
323 jum.assertEquals(folder1.children.length, 1);
324 jum.assertEquals(folder1.children[0], 'livemark1');
325
326 var livemark1 = couch.open('livemark1');
327 jum.assertNotNull(livemark1);
328 jum.assertEquals(livemark1.record_type, TYPE_FEED);
329 jum.assertEquals(livemark1.record_type_version, 2);
330 jum.assertEquals(livemark1.parent_guid, 'folder1');
331 jum.assertEquals(livemark1.title, 'Livemark 1');
332 jum.assertEquals(livemark1.site_uri, 'http://www.example.com/')
333 jum.assertEquals(livemark1.feed_uri, 'http://www.example.com/feed')
334
335 var bookmark1 = couch.open('bookmark1');
336 jum.assertNotNull(bookmark1);
337 jum.assertEquals(bookmark1.record_type, TYPE_BOOKMARK);
338 jum.assertEquals(bookmark1.record_type_version, 2);
339 jum.assertEquals(bookmark1.parent_guid, 'toolbar_profile_name');
340 jum.assertEquals(bookmark1.title, 'Bookmark 1');
341 jum.assertEquals(bookmark1.uri, 'http://www.example.com/bookmark1');
342
343 var menu = couch.open('menu_profile_name');
344 jum.assertNotNull(menu);
345 jum.assertEquals(menu.record_type, TYPE_FOLDER);
346 jum.assertEquals(menu.record_type_version, 2);
347 jum.assertEquals(menu.parent_guid, 'root_profile_name');
348 jum.assertEquals(menu.children.length, 2);
349 jum.assertEquals(menu.children[0], 'bookmark2');
350 jum.assertEquals(menu.children[1], 'separator1');
351
352 var bookmark2 = couch.open('bookmark2');
353 jum.assertNotNull(bookmark2);
354 jum.assertEquals(bookmark2.record_type, TYPE_BOOKMARK);
355 jum.assertEquals(bookmark2.record_type_version, 2);
356 jum.assertEquals(bookmark2.parent_guid, 'menu_profile_name');
357 jum.assertEquals(bookmark2.title, 'Bookmark 2');
358 jum.assertEquals(bookmark2.uri, 'http://www.example.com/bookmark2');
359
360 var separator1 = couch.open('separator1');
361 jum.assertNotNull(separator1);
362 jum.assertEquals(separator1.record_type, TYPE_SEPARATOR);
363 jum.assertEquals(separator1.record_type_version, 2);
364 jum.assertEquals(separator1.parent_guid, 'menu_profile_name');
365
366 var unfiled = couch.open('unfiled_profile_name');
367 jum.assertNotNull(unfiled);
368 jum.assertEquals(unfiled.record_type, TYPE_FOLDER);
369 jum.assertEquals(unfiled.record_type_version, 2);
370 jum.assertEquals(unfiled.parent_guid, 'root_profile_name');
371 jum.assertEquals(unfiled.children.length, 1);
372 jum.assertEquals(unfiled.children[0], 'bookmark3');
373
374 var bookmark3 = couch.open('bookmark3');
375 jum.assertNotNull(bookmark3);
376 jum.assertEquals(bookmark3.record_type, TYPE_BOOKMARK);
377 jum.assertEquals(bookmark3.record_type_version, 2);
378 jum.assertEquals(bookmark3.parent_guid, 'unfiled_profile_name');
379 jum.assertEquals(bookmark3.title, 'Bookmark 3');
380 jum.assertEquals(bookmark3.uri, 'http://www.example.com/bookmark3');
381};
382
383
384var test_upgrade_1_to_2 = function() {
385 make_sample_data_v1();
386 var sm = new migration.SchemaMigration(couch, 'profile_name');
387 sm.upgrade_1_to_2();
388
389 verify_sample_data_v2();
390
391 // The old documents for the special folders have been removed.
392 jum.assertNull(couch.open('obsolete_toolbar'));
393 jum.assertNull(couch.open('obsolete_menu'));
394 jum.assertNull(couch.open('obsolete_unfiled'));
395
396 // Unneeded attributes removed from annotation.
397 var bookmark1_doc = couch.open('bookmark1');
398 jum.assertUndefined(bookmark1_doc.application_annotations.Firefox.garbage);
399
400 // Orphaned items have been deleted.
401 jum.assertNull(couch.open('orphaned_bookmark'));
402};
403
404
405var test_migrate_v0 = function() {
406 make_sample_bookmarks();
407 make_sample_data_v0();
408
409 synchroniser.last_seq = couch.info().last_seq;
410 synchroniser.init();
411 synchroniser.sync();
412
413 verify_sample_data_v2();
414};
415
416var test_migrate_v1 = function() {
417 make_sample_bookmarks();
418 make_sample_data_v1();
419
420 synchroniser.last_seq = couch.info().last_seq;
421 synchroniser.init();
422 synchroniser.sync();
423
424 verify_sample_data_v2();
425};
0426
=== modified file 'mozmill/tests/test_sync_all.js'
--- mozmill/tests/test_sync_all.js 2011-03-04 13:02:54 +0000
+++ mozmill/tests/test_sync_all.js 2011-03-04 13:02:54 +0000
@@ -100,10 +100,23 @@
100};100};
101101
102var test_sync_remote = function() {102var test_sync_remote = function() {
103 couch.save({
104 _id: 'root_profile_name',
105 record_type: 'http://www.freedesktop.org/wiki/Specifications/desktopcouch/folder',
106 record_type_version: 2,
107 children: [
108 'toolbar_profile_name',
109 'menu_profile_name',
110 'unfiled_profile_name'
111 ]
112 });
113
103 var item_guid = '12345';114 var item_guid = '12345';
104 var doc = {115 var doc = {
105 _id: item_guid,116 _id: item_guid,
106 record_type: 'http://www.freedesktop.org/wiki/Specifications/desktopcouch/bookmark',117 record_type: 'http://www.freedesktop.org/wiki/Specifications/desktopcouch/bookmark',
118 record_type_version: 2,
119 parent_title: 'Bookmarks Toolbar',
107 parent_guid: 'toolbar_profile_name',120 parent_guid: 'toolbar_profile_name',
108 title: 'Bookmark title',121 title: 'Bookmark title',
109 uri: LOCAL_TEST_PAGE,122 uri: LOCAL_TEST_PAGE,
@@ -173,6 +186,7 @@
173 var doc = {186 var doc = {
174 _id: item_guid,187 _id: item_guid,
175 record_type: 'http://www.freedesktop.org/wiki/Specifications/desktopcouch/bookmark',188 record_type: 'http://www.freedesktop.org/wiki/Specifications/desktopcouch/bookmark',
189 record_type_version: 2,
176 parent_guid: 'toolbar_profile_name',190 parent_guid: 'toolbar_profile_name',
177 title: 'Bookmark title',191 title: 'Bookmark title',
178 uri: LOCAL_TEST_PAGE,192 uri: LOCAL_TEST_PAGE,
179193
=== modified file 'mozmill/tests/test_sync_from_couch.js'
--- mozmill/tests/test_sync_from_couch.js 2011-03-04 13:02:54 +0000
+++ mozmill/tests/test_sync_from_couch.js 2011-03-04 13:02:54 +0000
@@ -29,6 +29,7 @@
29 synchroniser.processRecord({29 synchroniser.processRecord({
30 _id: '12345',30 _id: '12345',
31 record_type: 'http://www.freedesktop.org/wiki/Specifications/desktopcouch/bookmark',31 record_type: 'http://www.freedesktop.org/wiki/Specifications/desktopcouch/bookmark',
32 record_type_version: 2,
32 parent_guid: 'toolbar_profile_name',33 parent_guid: 'toolbar_profile_name',
33 title: 'Bookmark title',34 title: 'Bookmark title',
34 uri: LOCAL_TEST_PAGE,35 uri: LOCAL_TEST_PAGE,
@@ -54,6 +55,7 @@
54 doc = {55 doc = {
55 _id: '12345',56 _id: '12345',
56 record_type: 'http://www.freedesktop.org/wiki/Specifications/desktopcouch/bookmark',57 record_type: 'http://www.freedesktop.org/wiki/Specifications/desktopcouch/bookmark',
58 record_type_version: 2,
57 parent_guid: 'toolbar_profile_name',59 parent_guid: 'toolbar_profile_name',
58 title: 'Bookmark title',60 title: 'Bookmark title',
59 uri: LOCAL_TEST_PAGE,61 uri: LOCAL_TEST_PAGE,
@@ -82,6 +84,7 @@
82 synchroniser.processRecord({84 synchroniser.processRecord({
83 _id: '12345',85 _id: '12345',
84 record_type: 'http://www.freedesktop.org/wiki/Specifications/desktopcouch/folder',86 record_type: 'http://www.freedesktop.org/wiki/Specifications/desktopcouch/folder',
87 record_type_version: 2,
85 parent_guid: 'toolbar_profile_name',88 parent_guid: 'toolbar_profile_name',
86 title: 'Folder',89 title: 'Folder',
87 children: [],90 children: [],
@@ -107,6 +110,7 @@
107 doc = {110 doc = {
108 _id: '12345',111 _id: '12345',
109 record_type: 'http://www.freedesktop.org/wiki/Specifications/desktopcouch/folder',112 record_type: 'http://www.freedesktop.org/wiki/Specifications/desktopcouch/folder',
113 record_type_version: 2,
110 parent_guid: 'toolbar_profile_name',114 parent_guid: 'toolbar_profile_name',
111 title: 'Folder',115 title: 'Folder',
112 children: [],116 children: [],
@@ -134,6 +138,7 @@
134 synchroniser.processRecord({138 synchroniser.processRecord({
135 _id: '12345',139 _id: '12345',
136 record_type: 'http://www.freedesktop.org/wiki/Specifications/desktopcouch/feed',140 record_type: 'http://www.freedesktop.org/wiki/Specifications/desktopcouch/feed',
141 record_type_version: 2,
137 parent_guid: 'toolbar_profile_name',142 parent_guid: 'toolbar_profile_name',
138 title: 'Livemark',143 title: 'Livemark',
139 site_uri: "http://www.example.com/",144 site_uri: "http://www.example.com/",
@@ -161,6 +166,7 @@
161 doc = {166 doc = {
162 _id: '12345',167 _id: '12345',
163 record_type: 'http://www.freedesktop.org/wiki/Specifications/desktopcouch/feed',168 record_type: 'http://www.freedesktop.org/wiki/Specifications/desktopcouch/feed',
169 record_type_version: 2,
164 parent_guid: 'toolbar_profile_name',170 parent_guid: 'toolbar_profile_name',
165 title: 'Livemark',171 title: 'Livemark',
166 site_uri: "http://www.example.com/",172 site_uri: "http://www.example.com/",
@@ -190,6 +196,7 @@
190 synchroniser.processRecord({196 synchroniser.processRecord({
191 _id: '12345',197 _id: '12345',
192 record_type: 'http://www.freedesktop.org/wiki/Specifications/desktopcouch/separator',198 record_type: 'http://www.freedesktop.org/wiki/Specifications/desktopcouch/separator',
199 record_type_version: 2,
193 parent_guid: 'toolbar_profile_name',200 parent_guid: 'toolbar_profile_name',
194 application_annotations: {201 application_annotations: {
195 Firefox: {202 Firefox: {
@@ -209,6 +216,7 @@
209 doc = {216 doc = {
210 _id: '12345',217 _id: '12345',
211 record_type: 'http://www.freedesktop.org/wiki/Specifications/desktopcouch/separator',218 record_type: 'http://www.freedesktop.org/wiki/Specifications/desktopcouch/separator',
219 record_type_version: 2,
212 parent_guid: 'toolbar_profile_name',220 parent_guid: 'toolbar_profile_name',
213 application_annotations: {221 application_annotations: {
214 Firefox: {222 Firefox: {
@@ -233,6 +241,7 @@
233 doc = {241 doc = {
234 _id: '12345',242 _id: '12345',
235 record_type: 'http://www.freedesktop.org/wiki/Specifications/desktopcouch/bookmark',243 record_type: 'http://www.freedesktop.org/wiki/Specifications/desktopcouch/bookmark',
244 record_type_version: 2,
236 parent_guid: 'toolbar_profile_name',245 parent_guid: 'toolbar_profile_name',
237 title: 'Bookmark title',246 title: 'Bookmark title',
238 uri: LOCAL_TEST_PAGE,247 uri: LOCAL_TEST_PAGE,
@@ -262,6 +271,7 @@
262 synchroniser.processRecord({271 synchroniser.processRecord({
263 _id: '12345',272 _id: '12345',
264 record_type: 'http://www.freedesktop.org/wiki/Specifications/desktopcouch/folder',273 record_type: 'http://www.freedesktop.org/wiki/Specifications/desktopcouch/folder',
274 record_type_version: 2,
265 parent_guid: 'toolbar_profile_name',275 parent_guid: 'toolbar_profile_name',
266 title: 'Folder',276 title: 'Folder',
267 children: ['67890'],277 children: ['67890'],
@@ -281,6 +291,7 @@
281 synchroniser.processRecord({291 synchroniser.processRecord({
282 _id: '67890',292 _id: '67890',
283 record_type: 'http://www.freedesktop.org/wiki/Specifications/desktopcouch/bookmark',293 record_type: 'http://www.freedesktop.org/wiki/Specifications/desktopcouch/bookmark',
294 record_type_version: 2,
284 parent_guid: '12345',295 parent_guid: '12345',
285 title: 'Bookmark title',296 title: 'Bookmark title',
286 uri: LOCAL_TEST_PAGE,297 uri: LOCAL_TEST_PAGE,
@@ -300,6 +311,7 @@
300 synchroniser.processRecord({311 synchroniser.processRecord({
301 _id: '67890',312 _id: '67890',
302 record_type: 'http://www.freedesktop.org/wiki/Specifications/desktopcouch/bookmark',313 record_type: 'http://www.freedesktop.org/wiki/Specifications/desktopcouch/bookmark',
314 record_type_version: 2,
303 parent_guid: '12345',315 parent_guid: '12345',
304 title: 'Bookmark title',316 title: 'Bookmark title',
305 uri: LOCAL_TEST_PAGE,317 uri: LOCAL_TEST_PAGE,
@@ -318,6 +330,7 @@
318 synchroniser.processRecord({330 synchroniser.processRecord({
319 _id: '12345',331 _id: '12345',
320 record_type: 'http://www.freedesktop.org/wiki/Specifications/desktopcouch/folder',332 record_type: 'http://www.freedesktop.org/wiki/Specifications/desktopcouch/folder',
333 record_type_version: 2,
321 parent_guid: 'toolbar_profile_name',334 parent_guid: 'toolbar_profile_name',
322 title: 'Folder',335 title: 'Folder',
323 children: ['67890'],336 children: ['67890'],
@@ -342,6 +355,7 @@
342 synchroniser.processRecord({355 synchroniser.processRecord({
343 _id: 'parent',356 _id: 'parent',
344 record_type: 'http://www.freedesktop.org/wiki/Specifications/desktopcouch/folder',357 record_type: 'http://www.freedesktop.org/wiki/Specifications/desktopcouch/folder',
358 record_type_version: 2,
345 parent_guid: 'toolbar_profile_name',359 parent_guid: 'toolbar_profile_name',
346 title: 'Folder',360 title: 'Folder',
347 children: ['child1', 'child2', 'child3', 'missing_child'],361 children: ['child1', 'child2', 'child3', 'missing_child'],
@@ -363,6 +377,7 @@
363 synchroniser.processRecord({377 synchroniser.processRecord({
364 _id: 'child1',378 _id: 'child1',
365 record_type: 'http://www.freedesktop.org/wiki/Specifications/desktopcouch/bookmark',379 record_type: 'http://www.freedesktop.org/wiki/Specifications/desktopcouch/bookmark',
380 record_type_version: 2,
366 parent_guid: 'parent',381 parent_guid: 'parent',
367 title: 'Child 1',382 title: 'Child 1',
368 uri: LOCAL_TEST_PAGE + "#child1",383 uri: LOCAL_TEST_PAGE + "#child1",
@@ -376,6 +391,7 @@
376 synchroniser.processRecord({391 synchroniser.processRecord({
377 _id: 'child3',392 _id: 'child3',
378 record_type: 'http://www.freedesktop.org/wiki/Specifications/desktopcouch/bookmark',393 record_type: 'http://www.freedesktop.org/wiki/Specifications/desktopcouch/bookmark',
394 record_type_version: 2,
379 parent_guid: 'parent',395 parent_guid: 'parent',
380 title: 'Child 3',396 title: 'Child 3',
381 uri: LOCAL_TEST_PAGE + "#child1",397 uri: LOCAL_TEST_PAGE + "#child1",
@@ -389,6 +405,7 @@
389 synchroniser.processRecord({405 synchroniser.processRecord({
390 _id: 'child2',406 _id: 'child2',
391 record_type: 'http://www.freedesktop.org/wiki/Specifications/desktopcouch/bookmark',407 record_type: 'http://www.freedesktop.org/wiki/Specifications/desktopcouch/bookmark',
408 record_type_version: 2,
392 parent_guid: 'parent',409 parent_guid: 'parent',
393 title: 'Child 2',410 title: 'Child 2',
394 uri: LOCAL_TEST_PAGE + "#child1",411 uri: LOCAL_TEST_PAGE + "#child1",
395412
=== modified file 'mozmill/tests/test_sync_to_couch.js'
--- mozmill/tests/test_sync_to_couch.js 2011-03-04 13:02:54 +0000
+++ mozmill/tests/test_sync_to_couch.js 2011-03-04 13:02:54 +0000
@@ -56,6 +56,7 @@
56 var doc = couch.open(item_guid);56 var doc = couch.open(item_guid);
57 jum.assertEquals(doc.record_type, "http://www.freedesktop.org/wiki/" +57 jum.assertEquals(doc.record_type, "http://www.freedesktop.org/wiki/" +
58 "Specifications/desktopcouch/bookmark");58 "Specifications/desktopcouch/bookmark");
59 jum.assertEquals(doc.record_type_version, 2);
59 jum.assertEquals(doc.application_annotations.Firefox.profile,60 jum.assertEquals(doc.application_annotations.Firefox.profile,
60 "profile_name");61 "profile_name");
61 jum.assertEquals(doc.parent_guid, "toolbar_profile_name");62 jum.assertEquals(doc.parent_guid, "toolbar_profile_name");
@@ -91,6 +92,7 @@
91 var doc = couch.open(folder_guid);92 var doc = couch.open(folder_guid);
92 jum.assertEquals(doc.record_type, "http://www.freedesktop.org/wiki/" +93 jum.assertEquals(doc.record_type, "http://www.freedesktop.org/wiki/" +
93 "Specifications/desktopcouch/folder");94 "Specifications/desktopcouch/folder");
95 jum.assertEquals(doc.record_type_version, 2);
94 jum.assertEquals(doc.application_annotations.Firefox.profile,96 jum.assertEquals(doc.application_annotations.Firefox.profile,
95 "profile_name");97 "profile_name");
96 jum.assertEquals(doc.parent_guid, "toolbar_profile_name");98 jum.assertEquals(doc.parent_guid, "toolbar_profile_name");
@@ -128,6 +130,7 @@
128 var doc = couch.open(item_guid);130 var doc = couch.open(item_guid);
129 jum.assertEquals(doc.record_type, "http://www.freedesktop.org/wiki/" +131 jum.assertEquals(doc.record_type, "http://www.freedesktop.org/wiki/" +
130 "Specifications/desktopcouch/feed");132 "Specifications/desktopcouch/feed");
133 jum.assertEquals(doc.record_type_version, 2);
131 jum.assertEquals(doc.application_annotations.Firefox.profile,134 jum.assertEquals(doc.application_annotations.Firefox.profile,
132 "profile_name");135 "profile_name");
133 jum.assertEquals(doc.parent_guid, "toolbar_profile_name");136 jum.assertEquals(doc.parent_guid, "toolbar_profile_name");
@@ -157,6 +160,7 @@
157 var doc = couch.open(item_guid);160 var doc = couch.open(item_guid);
158 jum.assertEquals(doc.record_type, "http://www.freedesktop.org/wiki/" +161 jum.assertEquals(doc.record_type, "http://www.freedesktop.org/wiki/" +
159 "Specifications/desktopcouch/separator");162 "Specifications/desktopcouch/separator");
163 jum.assertEquals(doc.record_type_version, 2);
160 jum.assertEquals(doc.application_annotations.Firefox.profile,164 jum.assertEquals(doc.application_annotations.Firefox.profile,
161 "profile_name");165 "profile_name");
162 jum.assertEquals(doc.parent_guid, "toolbar_profile_name");166 jum.assertEquals(doc.parent_guid, "toolbar_profile_name");
@@ -191,6 +195,7 @@
191 var doc = couch.open(root_guid);195 var doc = couch.open(root_guid);
192 jum.assertEquals(doc.record_type, "http://www.freedesktop.org/wiki/" +196 jum.assertEquals(doc.record_type, "http://www.freedesktop.org/wiki/" +
193 "Specifications/desktopcouch/folder");197 "Specifications/desktopcouch/folder");
198 jum.assertEquals(doc.record_type_version, 2);
194 jum.assertUndefined(doc.parent_guid);199 jum.assertUndefined(doc.parent_guid);
195 jum.assertEquals(doc.children.length, 3);200 jum.assertEquals(doc.children.length, 3);
196 jum.assertEquals(doc.children[0], synchroniser.guid_from_id(201 jum.assertEquals(doc.children[0], synchroniser.guid_from_id(

Subscribers

People subscribed via source and target branches