diff --git a/chrome/content/zotero/xpcom/data/relations.js b/chrome/content/zotero/xpcom/data/relations.js index 8c85b43733..3b259fda88 100644 --- a/chrome/content/zotero/xpcom/data/relations.js +++ b/chrome/content/zotero/xpcom/data/relations.js @@ -146,7 +146,7 @@ Zotero.Relations = new function () { * @return {Object[]} - An array of objects with a Zotero.DataObject as 'subject' * and a predicate string as 'predicate' */ - this.getByObject = function (objectType, object) { + this.getByObject = Zotero.Promise.coroutine(function* (objectType, object) { var objectsClass = Zotero.DataObjectUtilities.getObjectsClassForObjectType(objectType); var predicateIDs = []; var o = _subjectPredicatesByObject[objectType] @@ -156,13 +156,16 @@ Zotero.Relations = new function () { } var toReturn = []; for (let predicateID in o) { - o[predicateID].forEach(subjectID => toReturn.push({ - subject: objectsClass.get(subjectID), - predicate: Zotero.RelationPredicates.getName(predicateID) - })); + for (let subjectID of o[predicateID]) { + var subject = yield objectsClass.getAsync(subjectID); + toReturn.push({ + subject: subject, + predicate: Zotero.RelationPredicates.getName(predicateID) + }); + }; } return toReturn; - }; + }); this.updateUser = Zotero.Promise.coroutine(function* (fromUserID, toUserID) { @@ -179,9 +182,9 @@ Zotero.Relations = new function () { let objects = yield Zotero.DB.columnQueryAsync( sql, 'http://zotero.org/users/' + fromUserID + '/%' ); - Zotero.DB.addCurrentCallback("commit", function () { + Zotero.DB.addCurrentCallback("commit", function* () { for (let object of objects) { - let subPrefs = this.getByObject(type, object); + let subPrefs = yield this.getByObject(type, object); let newObject = object.replace( new RegExp("^http://zotero.org/users/" + fromUserID + "/(.*)"), "http://zotero.org/users/" + toUserID + "/$1" @@ -265,4 +268,4 @@ Zotero.Relations = new function () { } throw ("Invalid namespace in URI '" + uri + "' in Zotero.Relations._getPrefixAndValue()"); } -} \ No newline at end of file +} diff --git a/test/tests/itemsTest.js b/test/tests/itemsTest.js index ba0200c1e6..0e98cd4894 100644 --- a/test/tests/itemsTest.js +++ b/test/tests/itemsTest.js @@ -171,6 +171,55 @@ describe("Zotero.Items", function () { assert.equal(rels[0], item2URI); }) + it("should merge two items when servant is linked to an item absent from cache", function* () { + // two group libraries + var groupOneInfo = yield createGroup({ + id: 25026, + name: "Group One" + }); + var libraryOneID = Zotero.Groups.getLibraryIDFromGroupID(groupOneInfo.id); + + var groupTwoInfo = yield createGroup({ + id: 11592, + name: "Group Two" + }); + var libraryTwoID = Zotero.Groups.getLibraryIDFromGroupID(groupTwoInfo.id); + + assert.notEqual(libraryOneID, libraryTwoID); + + // two items in the first library + var item1 = yield createDataObject('item', {libraryID: libraryOneID}); + var item2 = yield createDataObject('item', {libraryID: libraryOneID}); + var item2URI = Zotero.URI.getItemURI(item2); + + // one item in the second library, linked to item2 as if it dragged and dropped from it + var itemX = yield createDataObject('item', {libraryID: libraryTwoID}); + yield itemX.addLinkedItem(item2); + + // check that the owl:sameAs relation has been registered okay + var rels = itemX.getRelationsByPredicate(Zotero.Relations.linkedObjectPredicate); + assert.lengthOf(rels, 1); + assert.equal(rels[0], item2URI); + + // the freshly minted item is in objectCache, but it might be absent in production, + // so we clobber it in this test + assert(!!Zotero.Items._objectCache[itemX.id], "itemX is in object cache") + delete Zotero.Items._objectCache[itemX.id]; + + // merge the two items in the first library + yield Zotero.Items.merge(item1, [item2]); + + // check that the merge completed okay + assert.isFalse(item1.deleted); + assert.isTrue(item2.deleted); + + // Check for merge-tracking relation + assert.isFalse(item1.hasChanged()); + var rels = item1.getRelationsByPredicate(Zotero.Relations.replacedItemPredicate); + assert.lengthOf(rels, 1); + assert.equal(rels[0], item2URI); + }) + it("should move merge-tracking relation from replaced item to master", function* () { var item1 = yield createDataObject('item'); var item2 = yield createDataObject('item');