diff --git a/chrome/content/zotero/xpcom/sync/syncLocal.js b/chrome/content/zotero/xpcom/sync/syncLocal.js index 4fd9451b77..9478878396 100644 --- a/chrome/content/zotero/xpcom/sync/syncLocal.js +++ b/chrome/content/zotero/xpcom/sync/syncLocal.js @@ -944,6 +944,13 @@ Zotero.Sync.Data.Local = { Zotero.debug(`Applying remote changes to ${objectType} ` + obj.libraryKey); Zotero.debug(result.changes); + // If there were local changes as well, keep object as unsynced and + // save the remote version to the sync cache rather than the merged + // version + if (result.localChanged) { + saveOptions.saveAsUnsynced = true; + saveOptions.cacheObject = jsonObject.data; + } Zotero.DataObjectUtilities.applyChanges( jsonDataLocal, result.changes ); @@ -955,10 +962,6 @@ Zotero.Sync.Data.Local = { jsonDataLocal[x] = jsonData[x]; }) jsonObject.data = jsonDataLocal; - // If there were additional local changes, keep as unsynced - if (result.localChanged) { - saveOptions.saveAsUnsynced = true; - } } } // Object doesn't exist locally diff --git a/test/tests/syncLocalTest.js b/test/tests/syncLocalTest.js index 185abddfc4..75cbc204ca 100644 --- a/test/tests/syncLocalTest.js +++ b/test/tests/syncLocalTest.js @@ -526,35 +526,54 @@ describe("Zotero.Sync.Data.Local", function() { } }) - it("should keep local item changes while applying non-conflicting remote changes", function* () { + it("should keep local item changes while applying non-conflicting remote changes", async function () { var libraryID = Zotero.Libraries.userLibraryID; - var type = 'item'; - let obj = yield createDataObject(type, { version: 5 }); - let data = obj.toJSON(); - yield Zotero.Sync.Data.Local.saveCacheObjects(type, libraryID, [data]); + let item = await createDataObject('item', { version: 5 }); + let data = item.toJSON(); + await Zotero.Sync.Data.Local.saveCacheObjects('item', libraryID, [data]); // Change local title - yield modifyDataObject(obj) - var changedTitle = obj.getField('title'); + await modifyDataObject(item) + item.setTags([ + { tag: 'A' } + ]); + await item.saveTx(); + var changedTitle = item.getField('title'); // Create remote version without title but with changed place - data.key = obj.key; + data.key = item.key; data.version = 10; + data.tags = [ + { + tag: 'B' + } + ] var changedPlace = data.place = 'New York'; let json = { - key: obj.key, + key: item.key, version: 10, - data: data + data }; - yield Zotero.Sync.Data.Local.processObjectsFromJSON( - type, libraryID, [json], { stopOnError: true } + var results = await Zotero.Sync.Data.Local.processObjectsFromJSON( + 'item', libraryID, [json], { stopOnError: true } ); - assert.equal(obj.version, 10); - assert.equal(obj.getField('title'), changedTitle); - assert.equal(obj.getField('place'), changedPlace); + assert.isTrue(results[0].processed); + assert.isUndefined(results[0].changes); + assert.isUndefined(results[0].conflicts); + assert.equal(item.version, 10); + assert.equal(item.getField('title'), changedTitle); + assert.equal(item.getField('place'), changedPlace); + assert.sameDeepMembers(item.getTags(), [{ tag: 'A' }, { tag: 'B' }]); // Item should be marked as unsynced so the local changes are uploaded - assert.isFalse(obj.synced); + assert.isFalse(item.synced); + // Sync cache should match remote + var cacheJSON = await Zotero.Sync.Data.Local.getCacheObject( + 'item', libraryID, data.key, data.version + ); + assert.notProperty(cacheJSON.data, 'title'); + assert.equal(cacheJSON.data.place, data.place); + assert.sameDeepMembers(cacheJSON.data.tags, data.tags); }); it("should keep local item changes while ignoring matching remote changes", async function () {