avoid relation to self after merging related items (#5488)

When copying over relations during merge of items
that are related to one another, avoid relating the
chosen main item to itself.

Fixes: #5487
This commit is contained in:
abaevbog 2025-08-15 00:40:01 -05:00 committed by Dan Stillman
parent 6c390ad56c
commit 5bbf4fb664
2 changed files with 36 additions and 1 deletions

View file

@ -1338,7 +1338,12 @@ Zotero.Items = function() {
// Add relations to toItem
let oldRelations = fromItem.getRelations();
for (let pred in oldRelations) {
oldRelations[pred].forEach(obj => toItem.addRelation(pred, obj));
oldRelations[pred].forEach((obj) => {
// Avoid adding a relation to self
if (obj !== toURI) {
toItem.addRelation(pred, obj);
}
});
}
// Remove merge-tracking relations from fromItem, so that there aren't two
@ -1359,6 +1364,8 @@ Zotero.Items = function() {
// so those will follow the merge-tracking relations and can optimize their
// path if they're resaved.
if (rel.subject.libraryID != toItem.libraryID) continue;
// Do not add a relation to self
if (rel.subject.id == toItem.id) continue;
rel.subject.removeRelation(rel.predicate, fromURI);
rel.subject.addRelation(rel.predicate, toURI);
await rel.subject.save();

View file

@ -81,5 +81,33 @@ describe("Duplicate Items", function () {
assert.isTrue(collection1.hasItem(item1.id));
assert.isTrue(collection2.hasItem(item1.id));
});
it("should not create a relation to self if related items are merged", async function () {
// Create 3 items related to each other
// item1 <-> item2, item2 <-> item3
var item1 = await createDataObject('item', { setTitle: true });
var item2 = item1.clone();
var item3 = item1.clone();
await item2.saveTx();
await item3.saveTx();
item1.addRelatedItem(item2);
item2.addRelatedItem(item1);
item2.addRelatedItem(item3);
item3.addRelatedItem(item2);
await item1.saveTx();
await item2.saveTx();
await item3.saveTx();
// Merge all 3 items into item1
await merge(item1.id);
// Item 1 should now be related to item2 and item3
assert.sameMembers(item1.relatedItems, [item2.key, item3.key]);
assert.sameMembers(item2.relatedItems, [item1.key]);
assert.sameMembers(item3.relatedItems, [item1.key]);
});
});
});