Fix erroneous sync conflict if creators are changed in the same way
This commit is contained in:
parent
d3bf704cf3
commit
ec0b993a17
2 changed files with 115 additions and 9 deletions
|
@ -1493,12 +1493,6 @@ Zotero.Sync.Data.Local = {
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'creators':
|
|
||||||
if (!Zotero.Creators.equals(c1.value, c2.value)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'tags':
|
case 'tags':
|
||||||
if (!Zotero.Tags.equals(c1.value, c2.value)) {
|
if (!Zotero.Tags.equals(c1.value, c2.value)) {
|
||||||
// If just a type difference, treat as modify with type 0 if
|
// If just a type difference, treat as modify with type 0 if
|
||||||
|
@ -1535,6 +1529,17 @@ Zotero.Sync.Data.Local = {
|
||||||
|
|
||||||
// Changes are equal or in conflict
|
// Changes are equal or in conflict
|
||||||
|
|
||||||
|
// Creators changed the same way on both sides
|
||||||
|
if (c1.field == 'creators' && c1.op == 'modify' && c2.op == 'modify') {
|
||||||
|
let creators1 = c1.value;
|
||||||
|
let creators2 = c2.value;
|
||||||
|
if (creators1.length == creators2.length
|
||||||
|
&& creators1.every((c, index) => Zotero.Creators.equals(c, creators2[index]))) {
|
||||||
|
changeset2.splice(j--, 1);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Removed on both sides
|
// Removed on both sides
|
||||||
if (c1.op == 'delete' && c2.op == 'delete') {
|
if (c1.op == 'delete' && c2.op == 'delete') {
|
||||||
changeset2.splice(j--, 1);
|
changeset2.splice(j--, 1);
|
||||||
|
|
|
@ -969,6 +969,13 @@ describe("Zotero.Sync.Data.Local", function() {
|
||||||
version: 1234,
|
version: 1234,
|
||||||
itemType: "book",
|
itemType: "book",
|
||||||
title: "Title 1",
|
title: "Title 1",
|
||||||
|
creators: [
|
||||||
|
{
|
||||||
|
firstName: "First1",
|
||||||
|
lastName: "Last1",
|
||||||
|
creatorType: "author"
|
||||||
|
}
|
||||||
|
],
|
||||||
url: "http://zotero.org/",
|
url: "http://zotero.org/",
|
||||||
publicationTitle: "Publisher", // Remove locally
|
publicationTitle: "Publisher", // Remove locally
|
||||||
extra: "Extra", // Removed on both
|
extra: "Extra", // Removed on both
|
||||||
|
@ -1003,6 +1010,19 @@ describe("Zotero.Sync.Data.Local", function() {
|
||||||
version: 1234,
|
version: 1234,
|
||||||
itemType: "book",
|
itemType: "book",
|
||||||
title: "Title 2", // Changed locally
|
title: "Title 2", // Changed locally
|
||||||
|
creators: [
|
||||||
|
{
|
||||||
|
firstName: "First1",
|
||||||
|
lastName: "Last1",
|
||||||
|
creatorType: "author"
|
||||||
|
},
|
||||||
|
// Same new creator on local and remote
|
||||||
|
{
|
||||||
|
firstName: "First2",
|
||||||
|
lastName: "Last2",
|
||||||
|
creatorType: "editor"
|
||||||
|
}
|
||||||
|
],
|
||||||
url: "https://www.zotero.org/", // Same change on local and remote
|
url: "https://www.zotero.org/", // Same change on local and remote
|
||||||
place: "Place", // Added locally
|
place: "Place", // Added locally
|
||||||
dateModified: "2015-05-14 14:12:34", // Changed locally and remotely, but ignored
|
dateModified: "2015-05-14 14:12:34", // Changed locally and remotely, but ignored
|
||||||
|
@ -1037,6 +1057,19 @@ describe("Zotero.Sync.Data.Local", function() {
|
||||||
version: 1235,
|
version: 1235,
|
||||||
itemType: "book",
|
itemType: "book",
|
||||||
title: "Title 1",
|
title: "Title 1",
|
||||||
|
creators: [
|
||||||
|
{
|
||||||
|
firstName: "First1",
|
||||||
|
lastName: "Last1",
|
||||||
|
creatorType: "author"
|
||||||
|
},
|
||||||
|
// Same new creator on local and remote
|
||||||
|
{
|
||||||
|
firstName: "First2",
|
||||||
|
lastName: "Last2",
|
||||||
|
creatorType: "editor"
|
||||||
|
}
|
||||||
|
],
|
||||||
url: "https://www.zotero.org/",
|
url: "https://www.zotero.org/",
|
||||||
publicationTitle: "Publisher",
|
publicationTitle: "Publisher",
|
||||||
date: "2015-05-15", // Added remotely
|
date: "2015-05-15", // Added remotely
|
||||||
|
@ -1273,8 +1306,6 @@ describe("Zotero.Sync.Data.Local", function() {
|
||||||
var result = Zotero.Sync.Data.Local._reconcileChanges(
|
var result = Zotero.Sync.Data.Local._reconcileChanges(
|
||||||
'item', cacheJSON, json1, json2, ignoreFields
|
'item', cacheJSON, json1, json2, ignoreFields
|
||||||
);
|
);
|
||||||
Zotero.debug('=-=-=-=');
|
|
||||||
Zotero.debug(result);
|
|
||||||
assert.lengthOf(result.changes, 0);
|
assert.lengthOf(result.changes, 0);
|
||||||
assert.sameDeepMembers(
|
assert.sameDeepMembers(
|
||||||
result.conflicts,
|
result.conflicts,
|
||||||
|
@ -1293,7 +1324,77 @@ describe("Zotero.Sync.Data.Local", function() {
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
})
|
});
|
||||||
|
|
||||||
|
it("should return conflict when creator changes can't be automatically resolved", function () {
|
||||||
|
var cacheJSON = {
|
||||||
|
key: "AAAAAAAA",
|
||||||
|
version: 1234,
|
||||||
|
title: "Title",
|
||||||
|
creators: [
|
||||||
|
{
|
||||||
|
firstName: "First1",
|
||||||
|
lastName: "Last1",
|
||||||
|
creatorType: "author"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
dateModified: "2015-05-14 12:34:56"
|
||||||
|
};
|
||||||
|
var json1 = {
|
||||||
|
key: "AAAAAAAA",
|
||||||
|
version: 1234,
|
||||||
|
title: "Title",
|
||||||
|
creators: [
|
||||||
|
{
|
||||||
|
firstName: "First2",
|
||||||
|
lastName: "Last2",
|
||||||
|
creatorType: "author"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
dateModified: "2015-05-14 14:12:34"
|
||||||
|
};
|
||||||
|
var json2 = {
|
||||||
|
key: "AAAAAAAA",
|
||||||
|
version: 1235,
|
||||||
|
title: "Title",
|
||||||
|
creators: [
|
||||||
|
{
|
||||||
|
firstName: "First3",
|
||||||
|
lastName: "Last3",
|
||||||
|
creatorType: "author"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
dateModified: "2015-05-14 13:45:12"
|
||||||
|
};
|
||||||
|
var ignoreFields = ['dateAdded', 'dateModified'];
|
||||||
|
var result = Zotero.Sync.Data.Local._reconcileChanges(
|
||||||
|
'item', cacheJSON, json1, json2, ignoreFields
|
||||||
|
);
|
||||||
|
assert.lengthOf(result.changes, 0);
|
||||||
|
assert.lengthOf(result.conflicts, 1);
|
||||||
|
assert.propertyVal(result.conflicts[0][0], 'field', 'creators');
|
||||||
|
assert.propertyVal(result.conflicts[0][0], 'op', 'modify');
|
||||||
|
assert.lengthOf(result.conflicts[0][0].value, 1);
|
||||||
|
assert.include(
|
||||||
|
result.conflicts[0][0].value[0],
|
||||||
|
{
|
||||||
|
firstName: 'First2',
|
||||||
|
lastName: 'Last2',
|
||||||
|
creatorType: 'author'
|
||||||
|
}
|
||||||
|
);
|
||||||
|
assert.propertyVal(result.conflicts[0][1], 'field', 'creators');
|
||||||
|
assert.propertyVal(result.conflicts[0][1], 'op', 'modify');
|
||||||
|
assert.lengthOf(result.conflicts[0][1].value, 1);
|
||||||
|
assert.include(
|
||||||
|
result.conflicts[0][1].value[0],
|
||||||
|
{
|
||||||
|
firstName: 'First3',
|
||||||
|
lastName: 'Last3',
|
||||||
|
creatorType: 'author'
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
it("should automatically merge array/object members and generate conflicts for field changes in absence of cached version", function () {
|
it("should automatically merge array/object members and generate conflicts for field changes in absence of cached version", function () {
|
||||||
var json1 = {
|
var json1 = {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue