Fix attachment matching filename isn't correctly retitled (#5637)

This commit is contained in:
Tom Najdek 2025-11-17 16:40:38 +01:00 • committed by GitHub
parent 2f2dfc9038
commit 49325e27d9
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 59 additions and 7 deletions

View file

@ -143,8 +143,9 @@ export async function renameFilesFromParent({ userLibrary = true, groupLibrary =
const oldBaseName = attachmentItem.attachmentFilename.replace(/\.[^.]+$/, '');
attachmentItem.attachmentFilename = newName;
// update title if it matches the old filename
if (attachmentItem.getField('title') === oldBaseName || attachmentItem.getField('title') === oldFileName) {
// update the title if it matches the old filename
const newTitleLC = attachmentItem.getField('title').toLowerCase();
if (newTitleLC === oldBaseName.toLowerCase() || newTitleLC === oldFileName.toLowerCase()) {
attachmentItem.setAutoAttachmentTitle({ ignoreAutoRenamePrefs: true });
}
@ -164,7 +165,7 @@ export async function renameFilesFromParent({ userLibrary = true, groupLibrary =
};
/**
* Renames an invidual attachment file based on its parent item's metadata.
* Renames an individual attachment file based on its parent item's metadata.
*
* @async
* @param {Zotero.Item} attachmentItem - The attachment item to be renamed.
@ -176,6 +177,7 @@ export async function renameFileFromParent(attachmentItem) {
throw new Error('Item ' + attachmentItem.itemID + ' cannot be renamed based on its parent item');
}
const oldName = attachmentItem.attachmentFilename;
const oldBaseName = attachmentItem.attachmentFilename.replace(/\.[^.]+$/, '');
const parentItemID = attachmentItem.parentItemID;
let parentItem = await Zotero.Items.getAsync(parentItemID);
@ -187,12 +189,13 @@ export async function renameFileFromParent(attachmentItem) {
let requiresSave = false;
if (!renamed && attachmentItem.isStoredFileAttachment()) {
// file is not present locally but we can still update filename in the database
// the file is not present locally, but we can still update the filename in the database
attachmentItem.attachmentFilename = newName;
requiresSave = true;
}
if (attachmentItem.getField('title') === oldBaseName) {
const newTitleLC = attachmentItem.getField('title').toLowerCase();
if (newTitleLC === oldBaseName.toLowerCase() || newTitleLC === oldName.toLowerCase()) {
attachmentItem.setAutoAttachmentTitle({ ignoreAutoRenamePrefs: true });
requiresSave = true;
}

View file

@ -2298,6 +2298,55 @@ describe("Zotero.Attachments", function () {
assert.equal(attachment.attachmentFilename, 'Title.png');
// After a manual rename, the title becomes the default for this type
assert.equal(attachment.getField('title'), Zotero.getString('file-type-image'));
});
it("should change attachment title if file basename matches the title", async function () {
var item = createUnsavedDataObject('item');
item.setField('title', 'Title');
await item.saveTx();
var attachment = await importFileAttachment('test.pdf', {
parentItemID: item.id,
title: "test"
});
assert.equal(attachment.attachmentFilename, 'test.pdf');
assert.equal(attachment.getField('title'), 'test');
await renameFileFromParent(attachment);
assert.equal(attachment.attachmentFilename, 'Title.pdf');
assert.equal(attachment.getField('title'), Zotero.getString('file-type-pdf'));
});
it("should change attachment title if file matches the title exactly", async function () {
var item = createUnsavedDataObject('item');
item.setField('title', 'Title');
await item.saveTx();
var attachment = await importFileAttachment('test.pdf', {
parentItemID: item.id,
title: "test.pdf"
});
assert.equal(attachment.attachmentFilename, 'test.pdf');
assert.equal(attachment.getField('title'), 'test.pdf');
await renameFileFromParent(attachment);
assert.equal(attachment.attachmentFilename, 'Title.pdf');
assert.equal(attachment.getField('title'), Zotero.getString('file-type-pdf'));
});
it("should change attachment title if file matches the title, case-insensitive", async function () {
var item = createUnsavedDataObject('item');
item.setField('title', 'Title');
await item.saveTx();
var attachment = await importFileAttachment('test.pdf', {
parentItemID: item.id,
title: "tESt.PDF"
});
assert.equal(attachment.attachmentFilename, 'test.pdf');
assert.equal(attachment.getField('title'), 'tESt.PDF');
await renameFileFromParent(attachment);
assert.equal(attachment.attachmentFilename, 'Title.pdf');
assert.equal(attachment.getField('title'), Zotero.getString('file-type-pdf'));
});
it("should restore an extension when renaming a misnamed file", async function () {
@ -2377,7 +2426,7 @@ describe("Zotero.Attachments", function () {
assert.equal(OS.Path.basename(path1), 'test.png');
assert.isTrue(await OS.File.exists(path1));
// pdf is the primary attachment, so renamed
// PDF is the primary attachment, so renamed
assert.equal(attachment2.attachmentFilename, 'Lorem.pdf');
let path2 = await attachment2.getFilePathAsync();
assert.equal(OS.Path.basename(path2), 'Lorem.pdf');