Close #975, Process conflicts for all batches together

This commit is contained in:
Dan Stillman 2016-05-03 23:09:38 -04:00
parent f8a0f9ad1d
commit 391f525a75
4 changed files with 577 additions and 480 deletions

View file

@ -547,334 +547,6 @@ describe("Zotero.Sync.Data.Local", function() {
});
});
describe("Conflict Resolution", function () {
beforeEach(function* () {
yield Zotero.DB.queryAsync("DELETE FROM syncCache");
})
after(function* () {
yield Zotero.DB.queryAsync("DELETE FROM syncCache");
})
it("should show conflict resolution window on item conflicts", function* () {
var libraryID = Zotero.Libraries.userLibraryID;
var type = 'item';
var objects = [];
var values = [];
var dateAdded = Date.now() - 86400000;
var downloadedJSON = [];
for (let i = 0; i < 2; i++) {
values.push({
left: {},
right: {}
});
// Create object in cache
let obj = objects[i] = yield createDataObject(
type,
{
version: 10,
dateAdded: Zotero.Date.dateToSQL(new Date(dateAdded), true),
// Set Date Modified values one minute apart to enforce order
dateModified: Zotero.Date.dateToSQL(
new Date(dateAdded + (i * 60000)), true
)
}
);
let jsonData = obj.toJSON();
jsonData.key = obj.key;
jsonData.version = 10;
let json = {
key: obj.key,
version: jsonData.version,
data: jsonData
};
yield Zotero.Sync.Data.Local.saveCacheObjects(type, libraryID, [json]);
// Create updated JSON, simulating a download
values[i].right.title = jsonData.title = Zotero.Utilities.randomString();
values[i].right.version = json.version = jsonData.version = 15;
downloadedJSON.push(json);
// Modify object locally
yield modifyDataObject(obj, undefined, { skipDateModifiedUpdate: true });
values[i].left.title = obj.getField('title');
values[i].left.version = obj.getField('version');
}
waitForWindow('chrome://zotero/content/merge.xul', function (dialog) {
var doc = dialog.document;
var wizard = doc.documentElement;
var mergeGroup = wizard.getElementsByTagName('zoteromergegroup')[0];
// 1 (remote)
// Remote version should be selected by default
assert.equal(mergeGroup.rightpane.getAttribute('selected'), 'true');
wizard.getButton('next').click();
// 2 (local)
assert.equal(mergeGroup.rightpane.getAttribute('selected'), 'true');
// Select local object
mergeGroup.leftpane.click();
assert.equal(mergeGroup.leftpane.getAttribute('selected'), 'true');
if (Zotero.isMac) {
assert.isTrue(wizard.getButton('next').hidden);
assert.isFalse(wizard.getButton('finish').hidden);
}
else {
// TODO
}
wizard.getButton('finish').click();
})
yield Zotero.Sync.Data.Local.processObjectsFromJSON(
type, libraryID, downloadedJSON, { stopOnError: true }
);
assert.equal(objects[0].getField('title'), values[0].right.title);
assert.equal(objects[1].getField('title'), values[1].left.title);
assert.equal(objects[0].getField('version'), values[0].right.version);
assert.equal(objects[1].getField('version'), values[1].left.version);
})
it("should resolve all remaining conflicts with one side", function* () {
var libraryID = Zotero.Libraries.userLibraryID;
var type = 'item';
var objects = [];
var values = [];
var downloadedJSON = [];
var dateAdded = Date.now() - 86400000;
for (let i = 0; i < 3; i++) {
values.push({
left: {},
right: {}
});
// Create object in cache
let obj = objects[i] = yield createDataObject(
type,
{
version: 10,
dateAdded: Zotero.Date.dateToSQL(new Date(dateAdded), true),
// Set Date Modified values one minute apart to enforce order
dateModified: Zotero.Date.dateToSQL(
new Date(dateAdded + (i * 60000)), true
)
}
);
let jsonData = obj.toJSON();
jsonData.key = obj.key;
jsonData.version = 10;
let json = {
key: obj.key,
version: jsonData.version,
data: jsonData
};
yield Zotero.Sync.Data.Local.saveCacheObjects(type, libraryID, [json]);
// Create new version in cache, simulating a download
values[i].right.title = jsonData.title = Zotero.Utilities.randomString();
values[i].right.version = json.version = jsonData.version = 15;
yield Zotero.Sync.Data.Local.saveCacheObjects(type, libraryID, [json]);
downloadedJSON.push(json);
// Modify object locally
yield modifyDataObject(obj, undefined, { skipDateModifiedUpdate: true });
values[i].left.title = obj.getField('title');
values[i].left.version = obj.getField('version');
}
waitForWindow('chrome://zotero/content/merge.xul', function (dialog) {
var doc = dialog.document;
var wizard = doc.documentElement;
var mergeGroup = wizard.getElementsByTagName('zoteromergegroup')[0];
var resolveAll = doc.getElementById('resolve-all');
// 1 (remote)
// Remote version should be selected by default
assert.equal(mergeGroup.rightpane.getAttribute('selected'), 'true');
assert.equal(
resolveAll.label,
Zotero.getString('sync.conflict.resolveAllRemoteFields')
);
wizard.getButton('next').click();
// 2 (local and Resolve All checkbox)
assert.equal(mergeGroup.rightpane.getAttribute('selected'), 'true');
mergeGroup.leftpane.click();
assert.equal(
resolveAll.label,
Zotero.getString('sync.conflict.resolveAllLocalFields')
);
resolveAll.click();
if (Zotero.isMac) {
assert.isTrue(wizard.getButton('next').hidden);
assert.isFalse(wizard.getButton('finish').hidden);
}
else {
// TODO
}
wizard.getButton('finish').click();
})
yield Zotero.Sync.Data.Local.processObjectsFromJSON(
type, libraryID, downloadedJSON, { stopOnError: true }
);
assert.equal(objects[0].getField('title'), values[0].right.title);
assert.equal(objects[0].getField('version'), values[0].right.version);
assert.equal(objects[1].getField('title'), values[1].left.title);
assert.equal(objects[1].getField('version'), values[1].left.version);
assert.equal(objects[2].getField('title'), values[2].left.title);
assert.equal(objects[2].getField('version'), values[2].left.version);
})
it("should handle local item deletion, keeping deletion", function* () {
var libraryID = Zotero.Libraries.userLibraryID;
var type = 'item';
var objectsClass = Zotero.DataObjectUtilities.getObjectsClassForObjectType(type);
var downloadedJSON = [];
// Create object, generate JSON, and delete
var obj = yield createDataObject(type, { version: 10 });
var jsonData = obj.toJSON();
var key = jsonData.key = obj.key;
jsonData.version = 10;
let json = {
key: obj.key,
version: jsonData.version,
data: jsonData
};
// Delete object locally
yield obj.eraseTx();
// Create new version in cache, simulating a download
json.version = jsonData.version = 15;
jsonData.title = Zotero.Utilities.randomString();
downloadedJSON.push(json);
var windowOpened = false;
waitForWindow('chrome://zotero/content/merge.xul', function (dialog) {
windowOpened = true;
var doc = dialog.document;
var wizard = doc.documentElement;
var mergeGroup = wizard.getElementsByTagName('zoteromergegroup')[0];
// Remote version should be selected by default
assert.equal(mergeGroup.rightpane.getAttribute('selected'), 'true');
assert.ok(mergeGroup.leftpane.pane.onclick);
// Select local deleted version
mergeGroup.leftpane.pane.click();
wizard.getButton('finish').click();
})
yield Zotero.Sync.Data.Local.processObjectsFromJSON(
type, libraryID, downloadedJSON, { stopOnError: true }
);
assert.isTrue(windowOpened);
obj = objectsClass.getByLibraryAndKey(libraryID, key);
assert.isFalse(obj);
})
it("should restore locally deleted item", function* () {
var libraryID = Zotero.Libraries.userLibraryID;
var type = 'item';
var objectsClass = Zotero.DataObjectUtilities.getObjectsClassForObjectType(type);
var downloadedJSON = [];
// Create object, generate JSON, and delete
var obj = yield createDataObject(type, { version: 10 });
var jsonData = obj.toJSON();
var key = jsonData.key = obj.key;
jsonData.version = 10;
let json = {
key: obj.key,
version: jsonData.version,
data: jsonData
};
yield obj.eraseTx();
// Create new version in cache, simulating a download
json.version = jsonData.version = 15;
jsonData.title = Zotero.Utilities.randomString();
downloadedJSON.push(json);
waitForWindow('chrome://zotero/content/merge.xul', function (dialog) {
var doc = dialog.document;
var wizard = doc.documentElement;
var mergeGroup = wizard.getElementsByTagName('zoteromergegroup')[0];
assert.isTrue(doc.getElementById('resolve-all').hidden);
// Remote version should be selected by default
assert.equal(mergeGroup.rightpane.getAttribute('selected'), 'true');
wizard.getButton('finish').click();
})
yield Zotero.Sync.Data.Local.processObjectsFromJSON(
type, libraryID, downloadedJSON, { stopOnError: true }
);
obj = objectsClass.getByLibraryAndKey(libraryID, key);
assert.ok(obj);
assert.equal(obj.getField('title'), jsonData.title);
})
it("should handle note conflict", function* () {
var libraryID = Zotero.Libraries.userLibraryID;
var type = 'item';
var objectsClass = Zotero.DataObjectUtilities.getObjectsClassForObjectType(type);
var downloadedJSON = [];
var noteText1 = "<p>A</p>";
var noteText2 = "<p>B</p>";
// Create object in cache
var obj = new Zotero.Item('note');
obj.setNote("");
obj.version = 10;
yield obj.saveTx();
var jsonData = obj.toJSON();
var key = jsonData.key = obj.key;
let json = {
key: obj.key,
version: jsonData.version,
data: jsonData
};
yield Zotero.Sync.Data.Local.saveCacheObjects(type, libraryID, [json]);
// Create new version in cache, simulating a download
json.version = jsonData.version = 15;
json.data.note = noteText2;
downloadedJSON.push(json);
// Modify local version
obj.setNote(noteText1);
waitForWindow('chrome://zotero/content/merge.xul', function (dialog) {
var doc = dialog.document;
var wizard = doc.documentElement;
var mergeGroup = wizard.getElementsByTagName('zoteromergegroup')[0];
// Remote version should be selected by default
assert.equal(mergeGroup.rightpane.getAttribute('selected'), 'true');
wizard.getButton('finish').click();
})
yield Zotero.Sync.Data.Local.processObjectsFromJSON(
type, libraryID, downloadedJSON, { stopOnError: true }
);
obj = objectsClass.getByLibraryAndKey(libraryID, key);
assert.ok(obj);
assert.equal(obj.getNote(), noteText2);
})
})
describe("#_reconcileChanges()", function () {
describe("items", function () {