Merge attachments and update notes (#2336)

We follow a different merge procedure for each attachment type:

- For PDF attachments, compare by MD5. If no match, get the top 50 words
  in the attachment's text and hash those, then check again for a match.
  Update references to item keys in notes and annotations.
- For web (snapshot / link) attachments, compare by title and URL.
  Prefer a title + URL match but accept a title-only match.
- For other attachment types, keep all attachments from all items being
  merged.

Also:

- Move most merge tests from Duplicates to Items#merge(). It just doesn't
  make sense to worry about the UI in these.
This commit is contained in:
Abe Jellinek 2022-03-09 22:26:26 +00:00 committed by GitHub
parent 8e8b03e5ff
commit ef82becf00
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
13 changed files with 753 additions and 95 deletions

View file

@ -20,6 +20,27 @@ describe("Duplicate Items", function () {
after(function () {
win.close();
});
async function merge(itemID) {
var userLibraryID = Zotero.Libraries.userLibraryID;
var selected = await cv.selectByID('D' + userLibraryID);
assert.ok(selected);
await waitForItemsLoad(win);
// Select the first item, which should select both
var iv = zp.itemsView;
var row = iv.getRowIndexByID(itemID);
var promise = iv.waitForSelect();
clickOnItemsRow(win, iv, row);
await promise;
// Click merge button
var button = win.document.getElementById('zotero-duplicates-merge-button');
button.click();
await waitForNotifierEvent('refresh', 'trash');
}
describe("Merging", function () {
it("should merge two items in duplicates view", function* () {
@ -28,28 +49,10 @@ describe("Duplicate Items", function () {
yield item2.saveTx();
var uri2 = Zotero.URI.getItemURI(item2);
var userLibraryID = Zotero.Libraries.userLibraryID;
var selected = yield cv.selectByID('D' + userLibraryID);
assert.ok(selected);
yield waitForItemsLoad(win);
// Select the first item, which should select both
var iv = zp.itemsView;
var row = iv.getRowIndexByID(item1.id);
assert.isNumber(row);
var promise = iv.waitForSelect();
clickOnItemsRow(win, iv, row);
assert.equal(iv.selection.count, 2);
yield promise;
// Click merge button
var button = win.document.getElementById('zotero-duplicates-merge-button');
button.click();
yield waitForNotifierEvent('refresh', 'trash');
yield merge(item1.id);
// Items should be gone
var iv = zp.itemsView;
assert.isFalse(iv.getRowIndexByID(item1.id));
assert.isFalse(iv.getRowIndexByID(item2.id));
assert.isTrue(item2.deleted);
@ -67,27 +70,11 @@ describe("Duplicate Items", function () {
var item2 = item1.clone();
item2.setCollections([collection2.id]);
yield item2.saveTx();
var userLibraryID = Zotero.Libraries.userLibraryID;
var selected = yield cv.selectByID('D' + userLibraryID);
assert.ok(selected);
yield waitForItemsLoad(win);
// Select the first item, which should select both
var iv = zp.itemsView;
var row = iv.getRowIndexByID(item1.id);
var promise = iv.waitForSelect();
clickOnItemsRow(win, iv, row);
yield promise;
// Click merge button
var button = win.document.getElementById('zotero-duplicates-merge-button');
button.click();
yield waitForNotifierEvent('refresh', 'trash');
yield merge(item1.id);
// Items should be gone
var iv = zp.itemsView;
assert.isFalse(iv.getRowIndexByID(item1.id));
assert.isFalse(iv.getRowIndexByID(item2.id));
assert.isTrue(item2.deleted);