From 6f1833f9360a43346df5f2d883d617bfa9ec66c8 Mon Sep 17 00:00:00 2001 From: Dan Stillman <dstillman@zotero.org> Date: Fri, 13 Apr 2018 23:36:09 -0400 Subject: [PATCH] Remove items from trash and My Publications when removed via sync Zotero.Item::fromJSON() wasn't properly accounting for missing 'deleted' or 'inPublications' properties. --- chrome/content/zotero/xpcom/data/item.js | 16 ++++---- test/tests/itemTest.js | 48 ++++++++++++++++++++++-- 2 files changed, 52 insertions(+), 12 deletions(-) diff --git a/chrome/content/zotero/xpcom/data/item.js b/chrome/content/zotero/xpcom/data/item.js index e66a48cdb3..bdcbdd6a70 100644 --- a/chrome/content/zotero/xpcom/data/item.js +++ b/chrome/content/zotero/xpcom/data/item.js @@ -4224,15 +4224,6 @@ Zotero.Item.prototype.fromJSON = function (json) { this[field] = val; break; - case 'parentItem': - this.parentKey = val; - break; - - case 'deleted': - case 'inPublications': - this[field] = !!val; - break; - case 'creators': this.setCreators(json.creators); break; @@ -4320,6 +4311,13 @@ Zotero.Item.prototype.fromJSON = function (json) { let note = json.note; this.setNote(note !== undefined ? note : ""); } + + // Update boolean fields that might not be present in JSON + ['deleted', 'inPublications'].forEach(field => { + if (json[field] || this[field]) { + this[field] = !!json[field]; + } + }); } diff --git a/test/tests/itemTest.js b/test/tests/itemTest.js index 63885fd052..567d75bdaf 100644 --- a/test/tests/itemTest.js +++ b/test/tests/itemTest.js @@ -1616,20 +1616,62 @@ describe("Zotero.Item", function () { assert.strictEqual(item.getField('accessDate'), ''); }); - it("should remove child item from collection if 'collections' property not provided", function* () { + it("should remove item from collection if 'collections' property not provided", function* () { var collection = yield createDataObject('collection'); // Create standalone attachment in collection var attachment = yield importFileAttachment('test.png', { collections: [collection.id] }); var item = yield createDataObject('item', { collections: [collection.id] }); + assert.isTrue(collection.hasItem(attachment.id)); var json = attachment.toJSON(); json.path = 'storage:test2.png'; // Add to parent, which implicitly removes from collection json.parentItem = item.key; delete json.collections; - Zotero.debug(json); attachment.fromJSON(json); - yield attachment.save(); + yield attachment.saveTx(); + assert.isFalse(collection.hasItem(attachment.id)); + }); + + it("should remove child item from parent if 'parentKey' property not provided", async function () { + var item = await createDataObject('item'); + var note = await createDataObject('item', { itemType: 'note', parentKey: [item.key] }); + + var json = note.toJSON(); + delete json.parentItem; + + note.fromJSON(json); + await note.saveTx(); + + assert.lengthOf(item.getNotes(), 0); + }); + + it("should remove item from trash if 'deleted' property not provided", async function () { + var item = await createDataObject('item', { deleted: true }); + + assert.isTrue(item.deleted); + + var json = item.toJSON(); + delete json.deleted; + + item.fromJSON(json); + await item.saveTx(); + + assert.isFalse(item.deleted); + }); + + it("should remove item from My Publications if 'inPublications' property not provided", async function () { + var item = await createDataObject('item', { inPublications: true }); + + assert.isTrue(item.inPublications); + + var json = item.toJSON(); + delete json.inPublications; + + item.fromJSON(json); + await item.saveTx(); + + assert.isFalse(item.inPublications); }); it("should ignore unknown fields", function* () {