--- a/browser/components/migration/tests/unit/test_Edge_db_migration.js
+++ b/browser/components/migration/tests/unit/test_Edge_db_migration.js
@@ -160,17 +160,17 @@ function convertValueForWriting(value, v
}
throw new Error("Unknown type " + valueType);
}
let initializedESE = false;
let eseDBWritingHelpers = {
- setupDB(dbFile, tableName, columns, rows) {
+ setupDB(dbFile, tables) {
if (!initializedESE) {
initializedESE = true;
loadLibraries();
KERNEL.SystemTimeToFileTime = gLibs.kernel.declare("SystemTimeToFileTime",
ctypes.default_abi, ctypes.bool, KERNEL.SYSTEMTIME.ptr, KERNEL.FILETIME.ptr);
declareESEFunction("CreateDatabaseW", ESE.JET_SESID, ESE.JET_PCWSTR,
@@ -216,48 +216,51 @@ let eseDBWritingHelpers = {
this._sessionCreated = true;
this._dbId = new ESE.JET_DBID();
this._dbPath = rootPath + "spartan.edb";
ESE.CreateDatabaseW(this._sessionId, this._dbPath, null,
this._dbId.address(), 0);
this._opened = this._attached = true;
- let tableCreationWrapper = createTableCreationWrapper(tableName, columns);
- ESE.CreateTableColumnIndexW(this._sessionId, this._dbId,
- tableCreationWrapper.table.address());
- this._tableId = tableCreationWrapper.table.tableid;
+ for (let [tableName, data] of tables) {
+ let {rows, columns} = data;
+ let tableCreationWrapper = createTableCreationWrapper(tableName, columns);
+ ESE.CreateTableColumnIndexW(this._sessionId, this._dbId,
+ tableCreationWrapper.table.address());
+ this._tableId = tableCreationWrapper.table.tableid;
- let columnIdMap = new Map();
- if (rows.length) {
- // Iterate over the struct we passed into ESENT because they have the
- // created column ids.
- let columnCount = ctypes.UInt64.lo(tableCreationWrapper.table.cColumns);
- let columnsPassed = tableCreationWrapper.table.rgcolumncreate;
- for (let i = 0; i < columnCount; i++) {
- let column = columnsPassed.contents;
- columnIdMap.set(column.szColumnName.readString(), column);
- columnsPassed = columnsPassed.increment();
+ let columnIdMap = new Map();
+ if (rows.length) {
+ // Iterate over the struct we passed into ESENT because they have the
+ // created column ids.
+ let columnCount = ctypes.UInt64.lo(tableCreationWrapper.table.cColumns);
+ let columnsPassed = tableCreationWrapper.table.rgcolumncreate;
+ for (let i = 0; i < columnCount; i++) {
+ let column = columnsPassed.contents;
+ columnIdMap.set(column.szColumnName.readString(), column);
+ columnsPassed = columnsPassed.increment();
+ }
+ ESE.ManualMove(this._sessionId, this._tableId,
+ -2147483648 /* JET_MoveFirst */, 0);
+ ESE.BeginTransaction(this._sessionId);
+ for (let row of rows) {
+ ESE.PrepareUpdate(this._sessionId, this._tableId, 0 /* JET_prepInsert */);
+ for (let columnName in row) {
+ let col = columnIdMap.get(columnName);
+ let colId = col.columnid;
+ let [val, valSize] = convertValueForWriting(row[columnName], col.coltyp);
+ /* JET_bitSetOverwriteLV */
+ ESE.SetColumn(this._sessionId, this._tableId, colId, val.address(), valSize, 4, null);
+ }
+ let actualBookmarkSize = new ctypes.unsigned_long();
+ ESE.Update(this._sessionId, this._tableId, null, 0, actualBookmarkSize.address());
+ }
+ ESE.CommitTransaction(this._sessionId, 0 /* JET_bitWaitLastLevel0Commit */);
}
- ESE.ManualMove(this._sessionId, this._tableId,
- -2147483648 /* JET_MoveFirst */, 0);
- ESE.BeginTransaction(this._sessionId);
- for (let row of rows) {
- ESE.PrepareUpdate(this._sessionId, this._tableId, 0 /* JET_prepInsert */);
- for (let columnName in row) {
- let col = columnIdMap.get(columnName);
- let colId = col.columnid;
- let [val, valSize] = convertValueForWriting(row[columnName], col.coltyp);
- /* JET_bitSetOverwriteLV */
- ESE.SetColumn(this._sessionId, this._tableId, colId, val.address(), valSize, 4, null);
- }
- let actualBookmarkSize = new ctypes.unsigned_long();
- ESE.Update(this._sessionId, this._tableId, null, 0, actualBookmarkSize.address());
- }
- ESE.CommitTransaction(this._sessionId, 0 /* JET_bitWaitLastLevel0Commit */);
}
} finally {
try {
this._close();
} catch (ex) {
Cu.reportError(ex);
}
}
@@ -296,17 +299,17 @@ add_task(function*() {
db.append("spartan.edb");
let logs = tempFile.clone();
logs.append("LogFiles");
logs.create(tempFile.DIRECTORY_TYPE, 0o600);
let creationDate = new Date(Date.now() - 5000);
const kEdgeMenuParent = "62d07e2b-5f0d-4e41-8426-5f5ec9717beb";
- let itemsInDB = [
+ let bookmarkReferenceItems = [
{
URL: "http://www.mozilla.org/",
Title: "Mozilla",
DateUpdated: new Date(creationDate.valueOf() + 100),
ItemId: "1c00c10a-15f6-4618-92dd-22575102a4da",
ParentId: kEdgeMenuParent,
IsFolder: false,
IsDeleted: false,
@@ -367,30 +370,59 @@ add_task(function*() {
URL: "http://www.iteminfavoritesbar.org/",
DateUpdated: new Date(creationDate.valueOf() + 800),
ItemId: "9f2b1ff8-b651-46cf-8f41-16da8bcb6791",
ParentId: "921dc8a0-6c83-40ef-8df1-9bd1c5c56aaf",
IsFolder: false,
IsDeleted: false,
},
];
- eseDBWritingHelpers.setupDB(db, "Favorites", [
- {type: COLUMN_TYPES.JET_coltypLongText, name: "URL", cbMax: 4096},
- {type: COLUMN_TYPES.JET_coltypLongText, name: "Title", cbMax: 4096},
- {type: COLUMN_TYPES.JET_coltypLongLong, name: "DateUpdated"},
- {type: COLUMN_TYPES.JET_coltypGUID, name: "ItemId"},
- {type: COLUMN_TYPES.JET_coltypBit, name: "IsDeleted"},
- {type: COLUMN_TYPES.JET_coltypBit, name: "IsFolder"},
- {type: COLUMN_TYPES.JET_coltypGUID, name: "ParentId"},
- ], itemsInDB);
+
+ let readingListReferenceItems = [
+ {
+ Title: "Some mozilla page",
+ URL: "http://www.mozilla.org/somepage/",
+ AddedDate: new Date(creationDate.valueOf() + 900),
+ ItemId: "c88426fd-52a7-419d-acbc-d2310e8afebe",
+ IsDeleted: false,
+ },
+ {
+ Title: "Some other page",
+ URL: "https://www.example.org/somepage/",
+ AddedDate: new Date(creationDate.valueOf() + 1000),
+ ItemId: "a35fc843-5d5a-4d1e-9be8-45214be24b5c",
+ IsDeleted: false,
+ },
+ ];
+ eseDBWritingHelpers.setupDB(db, new Map([["Favorites", {
+ columns: [
+ {type: COLUMN_TYPES.JET_coltypLongText, name: "URL", cbMax: 4096},
+ {type: COLUMN_TYPES.JET_coltypLongText, name: "Title", cbMax: 4096},
+ {type: COLUMN_TYPES.JET_coltypLongLong, name: "DateUpdated"},
+ {type: COLUMN_TYPES.JET_coltypGUID, name: "ItemId"},
+ {type: COLUMN_TYPES.JET_coltypBit, name: "IsDeleted"},
+ {type: COLUMN_TYPES.JET_coltypBit, name: "IsFolder"},
+ {type: COLUMN_TYPES.JET_coltypGUID, name: "ParentId"},
+ ],
+ rows: bookmarkReferenceItems,
+ }], ["ReadingList", {
+ columns: [
+ {type: COLUMN_TYPES.JET_coltypLongText, name: "URL", cbMax: 4096},
+ {type: COLUMN_TYPES.JET_coltypLongText, name: "Title", cbMax: 4096},
+ {type: COLUMN_TYPES.JET_coltypLongLong, name: "AddedDate"},
+ {type: COLUMN_TYPES.JET_coltypGUID, name: "ItemId"},
+ {type: COLUMN_TYPES.JET_coltypBit, name: "IsDeleted"},
+ ],
+ rows: readingListReferenceItems,
+ }]]));
let migrator = Cc["@mozilla.org/profile/migrator;1?app=browser&type=edge"]
.createInstance(Ci.nsIBrowserProfileMigrator);
- let bookmarksMigrator = migrator.wrappedJSObject.getESEMigratorForTesting(db);
- Assert.ok(bookmarksMigrator.exists, "Should recognize table we just created");
+ let bookmarksMigrator = migrator.wrappedJSObject.getBookmarksMigratorForTesting(db);
+ Assert.ok(bookmarksMigrator.exists, "Should recognize db we just created");
let source = MigrationUtils.getLocalizedString("sourceNameEdge");
let sourceLabel = MigrationUtils.getLocalizedString("importedBookmarksFolder", [source]);
let seenBookmarks = [];
let bookmarkObserver = {
onItemAdded(itemId, parentId, index, itemType, url, title, dateAdded, itemGuid, parentGuid) {
if (title.startsWith("Deleted")) {
@@ -421,20 +453,20 @@ add_task(function*() {
let menuParents = seenBookmarks.filter(item => item.parentGuid == PlacesUtils.bookmarks.menuGuid);
Assert.equal(menuParents.length, 1, "Should have a single folder added to the menu");
let toolbarParents = seenBookmarks.filter(item => item.parentGuid == PlacesUtils.bookmarks.toolbarGuid);
Assert.equal(toolbarParents.length, 1, "Should have a single item added to the toolbar");
let menuParentGuid = menuParents[0].itemGuid;
let toolbarParentGuid = toolbarParents[0].itemGuid;
- let expectedTitlesInMenu = itemsInDB.filter(item => item.ParentId == kEdgeMenuParent).map(item => item.Title);
+ let expectedTitlesInMenu = bookmarkReferenceItems.filter(item => item.ParentId == kEdgeMenuParent).map(item => item.Title);
// Hacky, but seems like much the simplest way:
expectedTitlesInMenu.push("Item in deleted folder (should be in root)");
- let expectedTitlesInToolbar = itemsInDB.filter(item => item.ParentId == "921dc8a0-6c83-40ef-8df1-9bd1c5c56aaf").map(item => item.Title);
+ let expectedTitlesInToolbar = bookmarkReferenceItems.filter(item => item.ParentId == "921dc8a0-6c83-40ef-8df1-9bd1c5c56aaf").map(item => item.Title);
let edgeNameStr = MigrationUtils.getLocalizedString("sourceNameEdge");
let importParentFolderName = MigrationUtils.getLocalizedString("importedBookmarksFolder", [edgeNameStr]);
for (let bookmark of seenBookmarks) {
let shouldBeInMenu = expectedTitlesInMenu.includes(bookmark.title);
let shouldBeInToolbar = expectedTitlesInToolbar.includes(bookmark.title);
if (bookmark.title == "Folder" || bookmark.title == importParentFolderName) {
@@ -453,18 +485,59 @@ add_task(function*() {
Assert.ok(true, "Expect toolbar and menu folders to not be in menu or toolbar");
} else {
// Bit hacky, but we do need to check this.
Assert.equal(bookmark.title, "Item in folder", "Subfoldered item shouldn't be in menu or toolbar");
let parent = seenBookmarks.find(maybeParent => maybeParent.itemGuid == bookmark.parentGuid);
Assert.equal(parent && parent.title, "Folder", "Subfoldered item should be in subfolder labeled 'Folder'");
}
- let dbItem = itemsInDB.find(someItem => bookmark.title == someItem.Title);
+ let dbItem = bookmarkReferenceItems.find(someItem => bookmark.title == someItem.Title);
if (!dbItem) {
Assert.equal(bookmark.title, importParentFolderName, "Only the extra layer of folders isn't in the input we stuck in the DB.");
Assert.ok([menuParentGuid, toolbarParentGuid].includes(bookmark.itemGuid), "This item should be one of the containers");
} else {
Assert.equal(dbItem.URL || null, bookmark.url && bookmark.url.spec, "URL is correct");
Assert.equal(dbItem.DateUpdated.valueOf(), (new Date(bookmark.dateAdded / 1000)).valueOf(), "Date added is correct");
}
}
+
+ MigrationUtils._importQuantities.bookmarks = 0;
+ seenBookmarks = [];
+ bookmarkObserver = {
+ onItemAdded(itemId, parentId, index, itemType, url, title, dateAdded, itemGuid, parentGuid) {
+ seenBookmarks.push({itemId, parentId, index, itemType, url, title, dateAdded, itemGuid, parentGuid});
+ },
+ onBeginUpdateBatch() {},
+ onEndUpdateBatch() {},
+ onItemRemoved() {},
+ onItemChanged() {},
+ onItemVisited() {},
+ onItemMoved() {},
+ };
+ PlacesUtils.bookmarks.addObserver(bookmarkObserver, false);
+
+ let readingListMigrator = migrator.wrappedJSObject.getReadingListMigratorForTesting(db);
+ Assert.ok(readingListMigrator.exists, "Should recognize db we just created");
+ migrateResult = yield new Promise(resolve => readingListMigrator.migrate(resolve)).catch(ex => {
+ Cu.reportError(ex);
+ Assert.ok(false, "Got an exception trying to migrate data! " + ex);
+ return false;
+ });
+ PlacesUtils.bookmarks.removeObserver(bookmarkObserver);
+ Assert.ok(migrateResult, "Migration should succeed");
+ Assert.equal(seenBookmarks.length, 3, "Should have seen 3 items being bookmarked (2 items + 1 folder).");
+ Assert.equal(seenBookmarks.filter(bm => bm.title != sourceLabel).length,
+ MigrationUtils._importQuantities.bookmarks,
+ "Telemetry should have items except for 'From Microsoft Edge' folders");
+ let readingListContainerLabel = MigrationUtils.getLocalizedString("importedEdgeReadingList");
+
+ for (let bookmark of seenBookmarks) {
+ if (readingListContainerLabel == bookmark.title) {
+ continue;
+ }
+ let referenceItem = readingListReferenceItems.find(item => item.Title == bookmark.title);
+ Assert.ok(referenceItem, "Should have imported what we expected");
+ Assert.equal(referenceItem.URL, bookmark.url.spec, "Should have the right URL");
+ readingListReferenceItems.splice(readingListReferenceItems.findIndex(item => item.Title == bookmark.title), 1);
+ }
+ Assert.ok(!readingListReferenceItems.length, "Should have seen all expected items.");
});